Envoy Proxy和Netflix Hystrix,究竟谁才是熔断王者?

Envoy Proxy和Netflix Hystrix,究竟谁才是熔断王者?

本文已获得 Christian Posta 授权,转载须获得许可。


作者:Christian Posta

翻译:崔秀龙@HPE

原文:Comparing Envoy and Istio Circuit Breaking With Netflix OSS Hystrix


当我们构建服务架构时(面向服务的架构,微服务,以及其他的东西),我们都要在网络上执行大量的调用。网络的脆弱是众所周知的,因此我们希望服务有一定的冗余,以便在系统故障期间能够保持服务能力。这一拼图中的重要一块就是智能的、通晓应用情况的负载均衡器。Matt Klein(注 1) 最近撰写了一篇关于现代负载均衡的大作(注 2),如果还没读过,建议读者首先阅读一下。


在构建大型、可靠的分布式系统尤其是在云端的微服务应用时,断路器(注 3)是一个重要的组件。有了这一组件,我们可以在系统发生持续故障的时候进行短路操作。断路器本身也是智能、应用感知的负载均衡器的组成部分。很多人都在或多或少的使用负载均衡。我们来看看 Netflix Hystrix(注 4)和 Envoy Proxy(注 5) 之间的差异。



熔断


断路(开路)的价值在于限制故障影响范围。我们希望控制、减少或或中断和故障系统之间的通信,从而降低故障系统的负载,有利于系统的恢复。例如有一个搜索服务,通过调用推荐服务来提供个性化的搜索结果;但是过程中发现推荐服务在很多不同调用中都返回了错误,所以我们可能应该停止调用一段时间。也许我们越是尝试就越会给系统造成压力,会造成情况的进一步恶化。经过考量,我们决定停止对这一服务的调用。这一方式和我们住宅中电气线路的熔断机制类似。如果出现故障,就应该断开故障部分,保护系统的其他部分。断路器模式强制我们的应用来正视网络问题——网络调用是可能、而且真的会出故障的,从而防止系统出现雪崩。这一技术的关键就是感知系统组件的健康并判断是否应该向某组件发送流量。



Netflix OSS Hystrix


Netflix OSS(注 6)在 2012 年发布了了一个断路器组件(注 7),称为 Hystrix(注 8)。Hystrix 是一个用于提供熔断能力的客户端 Java 库。Hystrix提供了这样一些特性(注 7)](medium.com/netflix-tech)。


来自“Making the Netflix API more resilient(注 7)”:


  • 自定义回落操作:在一些情况下,服务客户端库提供了一个回落方法供调用,或者其他情况下,我们可以使用本地的数据来生成回应。


  • 故障抑制:在这种情况下,回落方法简单的返回一个 null 值,如果这一服务返回的数据是可选项目,这种方式会很有帮助。


  • 快速失败:当目标服务的返回数据是必须的秦光霞,上面两种方法无法解决这一问题的,只能返回一个5xx响应。这对用户感知是很不好的,但是这一手段能能够保障服务器的健康,让系统能够更快的将失效服务进行修复。


可以用多种方式触发断路器(注 7)。


  • 对远程服务的请求发生超时。
  • 用于一个服务的线程池或任务队列容量满载
  • 用于调用服务的客户端库抛出异常。


Hystrix 熔断过程:


Netflix Hystrix 允许对网络交互进行非常细致的控制(注 9)。Hystrix 允许根据调用类型,对依赖服务进行精细的配置。假设我们对推荐引擎的调用绝大多数情况是只读的,那么断路器的配置就可以比较放松。


另外一个重要的事实是,Hystrix 的目的是及时断路,因此他把故障看做和超时是一致的。超时的故障点也可能处于客户一侧。Hystrix 对断路门槛的设置,并不区分故障究竟是服务端还是客户端的责任。


另外呼应前文:断路器真的只是智能、应用感知负载均衡技术的特性之一。在这种情况下“应用感知”的含义是:他的库在你的应用中运行。在 Netflix 生态系统中,还可以把 Hystrix 和 Netflix OSS Ribbon(注 10)这样的客户端负载均衡进行配对使用。



Service Mesh 的发展


服务架构持续向多样化方向演进,我们发现强制服务使用特定的库、框架或者语言是很难或者不实际的。随着 Service Mesh 走进视野,我们看到熔断能力有了独立于语言、框架的基础设施级的解决方案。Service Mesh 可以定义为:


一个处于服务之间的,去中心化的应用级网络基础设施,提供安全、弹性、监控和路由控制能力。


Service Mesh 可以使用不同的 L7(应用级)代理来扮演数据面角色,用于提供重试、超时、断路器等能力。本文中我们会看看 Envoy Proxy(注 10) 是如何完成熔断任务的。Envoy Proxy 是 Istio Service Mesh(注 11)的缺省的、开箱即用的代理,所以这里描述的特性同样也适用于 Istio。



Envoy Proxy / Istio Service Mesh


Envoy Proxy 将断路功能作为负载均衡和健康检查的一个子集。Envoy 将路由选择(选择进行通信的集群)的功能和通信功能(和确定的后端)分而治之。相对于其他粗粒度配置的负载均衡器,这一设计让 Envoy 与众不同。Envoy 可以有很多不同的“路由”尝试把流量发送给合适的后端。这些后端被称为cluster,每个cluster都可以有自己的负载均衡配置。每个cluster还可以有自己的被动健康检查(外部检测)配置。Envoy 有几个配置项用于熔断功能,这里可以逐个介绍一下。


这里定义一个外部cluster:


"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 断路器配置(注 11)。




断路器


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


这里我们目标是 HTTP 1.x 的负载。我们限制外来连接为 1,最大排队请求也是 1。另外还定义了最大重试次数。某种意义上,限制连接池以及请求数量的做法和 bulkhead(注 12) 以及 Netflix Hystrix 是类似的。如果客户端应用打开了超过限制的连接数量(这是一种软限制,有一定误差),我们会看到 Envoy 断掉多出的连接(注 13),并在统计报告中进行记录。



外部检测


上面我们看到,Envoy 所谓的熔断功能实际上更像是连接池控制。要完成这一功能,Envoy 做了一些称为outlier detection(注 14)。Envoy 持续对负载均衡池中的不同端点的操作进行统计。如果发现了超标行为,就把端点从负载均衡池中移除。我们可以看一下这一部分的配置代码:


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


这一配置的含义是:通信过程中,“如果发生了一次 5xx”错误,我们应该把这一主机标记为不健康,将其从负载均衡池中移除。我们还配置max_ejection_percent为100,也就是说,在发生这一情况时,我们愿意逐出所有端点。这一设置跟环境紧密相关,因此配置内容应该因地制宜,谨慎从事。我们希望尽可能的路由到一个主机,这样我们就不必冒着部分或级联故障的风险了。Envoy 缺省设置max_ejection_percent为10。


我们还设置逐出的时间基数为6000毫秒。一个主机被逐出负载均衡池的真实时间,由这一基数乘以被逐出时间得来,这样就可以对稳定性较差的主机实行更久的隔离。



集群恐慌


Envoy 外部检测和负载均衡功能中还有一点我们要知道的。如果太多的主机被这一过程逐出,就会进入集群恐慌模式(注 15),这种情况下,代理服务器会无视负载均衡池的健康标记,重新向所有主机发送数据。这是一个非常棒的机制。在分布式系统中,必须了解到的一点是,有时候“理论上”的东西可能不是正常情况,最好能降低一点要求来防止扩大故障影响。另外一方面,可以对这一比例进行控制(缺省情况下超过 50% 的驱逐就会进入恐慌状态),可以提高,也可以禁止这一阈值。设置为0之后,他的熔断行为就和 Netflix Hystrix 类似了。



可微调的熔断策略


库方式有个好处就是应用感知的可微调的熔断策略。Hystrix 文档中演示了针对同一集群的查询、读取、写入的不同调用,Hystrix FAQ 中说到:


通常情况下,一组负载均衡集群形成的单一网络路由会使用很多不同的 HystrixCommands 服务于很多不同类型的功能。


每个 HystrixCommands 都需要设置不同的吞吐限制、超时以及回落策略。


在 Envoy 中,我们能够通过路由匹配功能(注 16)获得同样的精确的熔断策略,这一功能和集群策略(注 17)结合,就可以指定在什么集群上进行什么操作了。



Istio 断路器


我们可以使用 Istio 的高级配置,来提供断路器能力。在 Istio 中,我们使用 目标策略(注 17)来配置负载均衡和断路器策略。下面是一个目标策略的例子,其中进行了断路器的设置:


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




熔断之后怎么办?


达到熔断标准的时候,会发生什么事情?Hystrix 中的回落策略是包含在库中并且能够进行编排的。Hystrix 让我们可以做一些后续操作,例如返回缓存值、返回缺省值甚至去调用其他服务。我们还可以获得清晰的关于故障的信息,并作出应用相关的决策。


在 Service Mesh 之中,因为没有内置库的支持,故障原因会比较隐蔽。这并不意味着我们的应用就不能有回落操作了(不管是传输还是客户端错误)。我认为对任何应用来说,不论他用的是不是特定库的框架,都会要尝试完成对客户的承诺。如果无法完成预定动作,就应该有一种优雅的降级方法。幸运的是,这种操作也不是非框架不可。多数语言都有内置的错误和异常处理能力,回落策略可以在异常处理过程中完成。




回放


  • 熔断能力是负载均衡的功能之一。
  • Hystrix 只提供了熔断能力,负载均衡要配合 Ribbon(或者其他客户端负载均衡库)完成。
  • Hystrix 以客户端库的形式提供了回落能力,非常强大。
  • Envoy 的负载均衡实现中包含了外部检测和断路器的功能。
  • Envoy 的熔断更像 Hystrix Bulkhead ,外部检测更像 Hystrix 断路器。
  • Envoy 具有很多缺省的久经考验的功能,例如集群恐慌。
  • Service Mesh 缺少故障回落的能力,只能让应用来完成这一任务。



点击阅读原文即可阅读更多Christian Posta文章~

Contact with Christian Posta@twitter.com/christianpo


1.twitter.com/mattklein12

2.blog.envoyproxy.io/intr

3.martinfowler.com/bliki/

4.github.com/Netflix/Hyst

5.envoyproxy.io/

6.netflix.github.io

7.medium.com/netflix-tech

8.github.com/Netflix/Hyst

9.github.com/Netflix/Hyst

10.envoyproxy.io/

11.envoyproxy.io/docs/envo

12.developers.redhat.com/b

13.blog.christianposta.com

14.envoyproxy.io/docs/envo

15.envoyproxy.io/docs/envo

16.envoyproxy.io/docs/envo


推荐阅读

Envoy如何打败Linkerd成为L7负载平衡器的最佳选择?

Serverless遇上ServiceMesh,是珠联璧合还是流于形式?

Ambassador和Istio:边缘代理和服务网格

3种Ansible Roles分步指南,教你如何使用Weave Scope探索微服务通信和服务网格

最强解析!条分缕析拆解现代网络负载均衡和代理技术


ServiceMesh中文社区:

ServiceMesh中文社区(servicemesh.cn)已上线,Istio、Conduit官方文档翻译版已在社区发布,欢迎大家登录浏览。


ServiceMesh微信交流群:

添加微信xiaoshu062,备注:服务网格,即可加入Service Mesh微信交流群。

发布于 2018-02-01