断路器Netflix OSS Hystrix和Istio的Envoy比较


当我们构建微服务架构时,我们总会通过网络进行更多的调用。但是构建冗余、弹性的分布式系统是一个难题,它需要一个智能的、应用程序感知的负载平衡。Matt Klein最近写了一篇关于现代负载平衡的精彩文章,你现在阅读一下。
断路器模式是建设大型的、有弹性的分布式系统的一个重要模式,断路是智能、应用程序感知负载平衡的子集功能。您要么明确地进行负载平衡,要么让它隐式悄悄发生(装作不知道)。

断路
我们使用断路功能来帮助防止部分或全部级联故障,我们希望控制/减少/消除不健康系统的流量。也许我们重试的次数越多,我们对该系统施加的压力就越大,我们是否让它进一步降级?在一段时间内,我们可能决定进行“快速失败”并且不允许任何调用。断路器模式迫使我们必须处理我们的网络调用可能并且确实会发生失败的事实,并帮助保护整个系统免于级联故障。它关注的是感知系统组件的健康状况以及我们是否应该将流量路由到它们。

Netflix OSS Hystrix
Netflix OSS 于2012年发布了一款名为Netflix OSS Hystrix的[url=https://medium.com/netflix-techblog/introducing-hystrix-for-resilience-engineering-13531c1ab362]断路器实施方案[/url]。Hystrix是一个客户端Java库,用于获取断路行为。Hystrix 提供以下行为

  • 自定义回退方法。
  • 失败沉默 - 在这种情况下,回退方法只返回一个空值,如果被调用的服务提供的数据对于将被发送回请求客户端的响应是可选的,这将非常有用。
  • 快速失败 - 用于需要数据或没有良好回退并导致客户端获得5xx响应的情况。这可能会对设备用户体验产生负面影响,这并不理想,但它可以使API服务器保持健康状态,并使系统能够在故障服务再次可用时快速恢复。

Hystrix非常明显地表示,为了断路,故障发生时,故障/超时也没有区别。也就是说,它可能发生在传输中或客户端代码本身中。无论故障发生在何处,Hystrix都会检测断路阈值。
最后,正如我之前提到的:断路实际上只是智能,应用感知负载平衡的一个特殊功能。在Netflix OSS生态系统中,您还可以将Hystrix与Netflix OSS Ribbon配对,后者是另一个用于执行客户端负载平衡的应用程序库。

服务网格的演变
随着您的服务架构变得更加异构,您会发现将服务实现限制到特定的库,框架甚至Java语言都是很困难(或不切实际)。随着服务网络的发展,我们看到一些弹性模式,如断路,在基础设施中作为语言/框架独立的解决方案实现。
服务网格可能依赖于其“数据面板”中的不同L7(应用级别)代理来实现弹性功能,如重试,超时,断路器等。

Envoy Proxy和Istio服务网格
Envoy将断路功能视为负载平衡和运行状况检查的子集。Envoy 将路由功能从到后端的通信中独立出来,这是一个重要的考虑因素,也是让Envoy超越其他负载均衡器粗粒度弹性的原因。Envoy可能有许多不同的“路由”,试图将流量映射到适当的后端。这些后端被描述为“集群”,每个集群可以拥有自己的特定于集群的配置以进行负载平衡。每个集群还可以拥有自己的配置,用于被动健康检查(异常值检测)。
我们可以像这样定义一个出站集群:

"clusters": [
  {
   
"name": "httpbin_service",
   
"connect_timeout_ms": 5000,
   
"type": "static",
   
"lb_type": "round_robin",
   
"hosts": [
      {
       
"url": "tcp://172.17.0.2:8080"
      },{
       
"url": "tcp://172.17.0.3:8080"
      }
    ],

我们可以在这个例子中看到我们有一个名为的集群httpbin_service,我们将使用round_robin负载平衡,我们将平衡两个主机。
让我们添加Envoy的断路器配置

"circuit_breakers": {
     
"default": {
       
"max_connections": 1,
       
"max_pending_requests": 1,
       
"max_retries": 3
      }

这里我们的目标是HTTP 1.x工作负载。我们将出站连接数限制1,最大挂起请求数1,我们还定义了最大重试次数。在某些方面,限制请求的连接池和数量的这种行为类似于 Netflix Hystrix 提供的 bulkhead 功能,如果我们的应用程序打开了比这些设置更多的连接(实际上有一些余地 - 这些不是硬限制),Envoy将打开断路,并在其统计中报告这些事件,请参阅此博文详细介绍

异常值检测
到目前为止,我们看到Envoy所谓的“断路器”实际上更接近 connection-pool bulkheads,为了实现“断路”行为,Envoy做了一个叫做离群检测的事情。Envoy会在特定群集的负载平衡池中保留有关不同端点的操作的统计信息。如果检测到异常行为,则可以从负载平衡池中排除该端点。
我们来看一下异常值检测的示例配置:

 "outlier_detection" : {
     
"consecutive_5xx": 1,
     
"max_ejection_percent": 100,
     
"interval_ms": 1000,
     
"base_ejection_time_ms": 60000
    }

此配置在我们与上游主机的通信中显示“如果我们有1个 5xx”错误,我们应将其标记为不健康,并暂时将其从此群集的负载平衡池中删除。
我们还配置max_ejection_percent为100意味着我们愿意拒绝遇到故障的所有主机。此设置非常特定于环境,您需要注意配置它。理想情况下,我们希望尽一切可能路由到主机,以免引入部分或级联故障。特使默认将设置max_ejection_percent为10。
我们还将eject基础周期设置为6000ms。主机从负载平衡池中排除弹射的实际时间是这个“基础”设置乘以它被弹出的次数。这使我们能够更严厉地惩罚那些看起来一直不太可靠的主机。

集群恐慌
我们还应该注意Envoy异常值检测和负载平衡。如果通过异常检测弹出太多主机,我们可能会达到群集全局“恐慌”模式,这意味着代理将不再相信它看到的负载平衡池的运行状况并再次开始路由到所有主机。这是一个非常强大的后备功能,在分布式系统中,您必须意识到有时您在“理论”中对世界的看法是不正确的,并且最好降级到不鼓励更多级联故障的模式。
另一方面,您可以控制此恐慌百分比(默认情况下,如果超过50%的负载平衡池被弹出,Envoy会惊慌)并增加恐慌阈值(> 50%)甚至完全禁用(将其设置为0)。设置它为0会使Envoy的断路功能之间的行为更像Netflix Hystrix

细粒度的断路策略
库包的一个好处是我们可以应用的细粒度应用感知电路中断策略。Hystrix通常是通过一组负载均衡器的单个网络路由将提供许多不同类型的功能,在几个不同的HyrxScript命令中。每个HyrScript命令都需要设置不同的能力:吞吐量限制、超时值和回退策略。

而对于Envoy,我们可以通过路由匹配来完成相同的外回路的中断策略,指定我们想要操作哪些确切的集群调用以及特定的集群策略

使用Istio进行细粒度断路
我们可以使用Istio更高级别的配置来指定细粒度的断路,在Istio中,我们使用DestinationPolicies来配置负载平衡和回路中断策略。以下是在Istio中指定断路功能的destiantion策略示例:

metadata:
  name: reviews-cb-policy
  namespace: default
spec:
  destination:
    name: reviews
    labels:
      version: v1
  circuitBreaker:
    simpleCb:
      maxConnections: 100
      httpMaxRequests: 1000
      httpMaxRequestsPerConnection: 10
      httpConsecutiveErrors: 7
      sleepWindow: 15m
      httpDetectionInterval: 5m


断路激活
使用Hystrix,回退的概念内置于库中,可以由库编排。在Hystrix中,我们可以执行缓存结果,回退到默认值,甚至通过调用不同的服务来获取备用路径。我们还可以获得有关失败的详细信息,并制定特定于应用程序的决策。
使用服务网格,目前没有用于上下文传播故障的专用库,故障原因更加不透明。
这并不意味着我们的应用程序无法进行回退(对于传输和客户端特定的错误)。我认为对于任何应用程序的协议都非常重要,无论是使用特定于库的框架还是不是使用,都要始终遵守它试图为其客户保留的承诺。如果它发现它无法完成其预期的操作,它应该找到一种优雅降级的方法。幸运的是,您不需要特定于应用程序的框架。大多数语言都有内置错误和异常捕获和处理。应在这些异常路径中实现回退。


概括

  • 断路是负载平衡器的特殊行为
  • Hystrix只执行断路功能; 负载均衡可以与Ribbon(或任何客户端负载平衡库)配对
  • Hystrix将“快速失败回退”概念作为库包/框架的关注点,并使其成为前沿和中心
  • 作为其负载平衡实施的一部分,Envoy具有断路和异常检测功能
  • Envoy“断路器”更像是Hystrix的bulkhead,“异常检测”更类似于Hystrix断路器
  • Envoy拥有许多默认的生产/战斗力的测试功能,如恐慌阈值
  • 服务网格缺乏向应用程序提供故障上下文的能力(请继续关注!)