SpringCloud(四):Hystrix熔断器介绍【Greenwich 版】

在这里插入图片描述
Hystrix的中文含义是 “豪猪”,豪猪周身长满了刺,能保护自己不受天敌的伤害,代表了一种防御机制,这与 Hystrix 本身的功能不谋而合,因此 Netflix 团队将该框架命名为 Hystrix,并使用了对应的卡通形象做作为 logo。

分布式系统中经常会出现某个基础服务不可用造成整个系统不可用的情况,这种现象被称为服务雪崩效应。为了应对服务雪崩,一种常见的做法是手动服务降级。而 Hystrix 的出现,给我们提供了另一种选择。

服务雪崩效应的定义

服务雪崩效应是一种因 服务提供者 的不可用导致 服务调用者 的不可用,并将不可用 逐渐放大 的过程。如果所示:
在这里插入图片描述
上图中,A 为服务提供者,B 为 A 的服务调用者,C 和 D 是 B 的服务调用者。当 A 的不可用,引起 B 的不可用,并将不可用逐渐放大 C 和 D 时,服务雪崩就形成了。

服务雪崩形成的原因

我把服务雪崩的参与者简化为 服务提供者 和 服务调用者,并将服务雪崩产生的过程分为以下三个阶段来分析形成的原因:

  1. 服务提供者不可用
  2. 重试加大流量
  3. 服务调用者不可用

在这里插入图片描述
服务雪崩的每个阶段都可能由不同的原因造成,比如造成 服务不可用 的原因有:

  • 硬件故障
  • 程序 Bug
  • 缓存击穿
  • 用户大量请求

硬件故障可能为硬件损坏造成的服务器主机宕机,网络硬件故障造成的服务提供者的不可访问。
缓存击穿一般发生在缓存应用重启,所有缓存被清空时,以及短时间内大量缓存失效时。大量的缓存不命中,使请求直击后端,造成服务提供者超负荷运行,引起服务不可用。
在秒杀和大促开始前,如果准备不充分,用户发起大量请求也会造成服务提供者的不可用。

而形成 重试加大流量 的原因有:

  • 用户重试
  • 代码逻辑重试

在服务提供者不可用后,用户由于忍受不了界面上长时间的等待,而不断刷新页面甚至提交表单。
服务调用端的会存在大量服务异常后的重试逻辑。这些重试都会进一步加大请求流量。
最后,服务调用者不可用 产生的主要原因是:

  • 同步等待造成的资源耗尽

当服务调用者使用 同步调用 时,会产生大量的等待线程占用系统资源。一旦线程资源被耗尽,服务调用者提供的服务也将处于不可用状态,于是服务雪崩效应产生了。

服务雪崩的应对策略

针对造成服务雪崩的不同原因,可以使用不同的应对策略:

  • 流量控制
  • 改进缓存模式
  • 服务自动扩容
  • 服务调用者降级服务

流量控制 的具体措施包括:

  • 网关限流
  • 用户交互限流
  • 关闭重试

因为Nginx的高性能, 目前一线互联网公司大量采用Nginx+Lua的网关进行流量控制, 由此而来的OpenResty也越来越热门.

用户交互限流的具体措施有: 1. 采用加载动画,提高用户的忍耐等待时间. 2. 提交按钮添加强制等待时间机制.

改进缓存模式 的措施包括:

  • 缓存预加载
  • 同步改为异步刷新

服务自动扩容 的措施主要有:

  • AWS的auto scaling

服务调用者降级服务 的措施包括:

  • 资源隔离
  • 对依赖服务进行分类
  • 不可用服务的调用快速失败

资源隔离主要是对调用服务的线程池进行隔离.

我们根据具体业务,将依赖服务分为: 强依赖和弱依赖. 强依赖服务不可用会导致当前业务中止,而弱依赖服务的不可用不会导致当前业务的中止.

不可用服务的调用快速失败一般通过 超时机制, 熔断器 和熔断后的 降级方法 来实现.

使用Hystrix预防服务雪崩

Hystrix的设计原则包括:

  • 资源隔离
  • 熔断器
  • 命令模式

资源隔离
货船为了进行防止漏水和火灾的扩散,会将货仓分隔为多个, 如下图所示:
在这里插入图片描述
这种资源隔离减少风险的方式被称为:Bulkheads(舱壁隔离模式).
Hystrix将同样的模式运用到了服务调用者上,Hystrix的隔绝策略分为两种:线程隔离信号量隔离

线程隔离:Hystrix在用户请求和服务之间加入了线程池。Hystrix为每个依赖调用分配一个小的线程池。用户的请求将不再直接访问服务,而是通过线程池中的空闲线程来访问服务,如果线程池已满调用将被立即拒绝,进行降级处理,用户的请求不会被阻塞,至少可以看到一个执行结果(例如返回友好的提示信息),而不是无休止的等待或者看到系统崩溃。
信号量隔离:每次调用线程,当前请求通过计数信号量进行限制,当信号大于了最大请求数时,进行限制,调用fallback接口快速返回。

官网对信号量隔离的描述建议
Generally the only time you should use semaphore isolation for HystrixCommands is when the call is so high volume (hundreds per second, per instance) that the overhead of separate threads is too high; this typically only applies to non-network calls.
理解下两点:

  • 隔离的细粒度太高,数百个实例需要隔离,此时用线程池做隔离开销过大
  • 通常这种都是非网络调用的情况下

一般来说,只有当调用负载非常高时(例如每个实例每秒调用数百次)才需要使用信号量隔离,因为这种场景下使用线程隔离开销会比较高。信号量隔离一般仅适用于非网络调用的隔离。Hystrix中默认并且推荐使用线程隔离。

二者的比较

隔离策略线程隔离信号量隔离
线程HystrixCommand将会在单独的线程上执行HystrixCommand将会在调用线程上执行
开销排队、调度、上下文开销等无线程切换,开销低
异步支持不支持
并发支持支持(最大线程池大小)支持(最大信号量上限)
是否支持超时支持,直接返回不支持,如果阻塞,只能通过调用协议(如:socket超时才能返回)
是否支持熔断支持,当线程池到达maxSize后,再请求会触发fallback接口进行熔断支持,当信号量达到maxConcurrentRequests后。再请求会触发fallback

熔断器模式
熔断器模式定义了熔断器开关相互转换的逻辑:
在这里插入图片描述
服务的健康状况 = 请求失败数 / 请求总数.
熔断器开关由关闭到打开的状态转换是通过当前服务健康状况和设定阈值比较决定的.

当熔断器开关关闭时, 请求被允许通过熔断器. 如果当前健康状况高于设定阈值, 开关继续保持关闭. 如果当前健康状况低于设定阈值, 开关则切换为打开状态,当熔断器开关打开时, 请求被禁止通过.

当熔断器开关处于打开状态, 经过一段时间后(默认5s), 熔断器会自动进入半开状态, 这时熔断器只允许一个请求通过. 当该请求调用成功时, 熔断器恢复到关闭状态. 若该请求失败, 熔断器继续保持打开状态, 接下来的请求被禁止通过.

熔断器的开关能保证服务调用者在调用异常服务时, 快速返回结果, 避免大量的同步等待. 并且熔断器能在一段时间后继续侦测请求执行结果, 提供恢复服务调用的可能.

命令模式
Hystrix有两个请求命令 HystrixCommandHystrixObservableCommand
其中HystrixCommand依赖调用方法是run,服务降级方法是getFallback
HystrixObservableCommand依赖调用方法是construct,服务降级方法是resumeWithFallback

HystrixCommand是发出一个请求,返回一个结果

  • execute() — 从依赖的服务返回一个单一的结果对象,同步阻塞式;
  • queue() — 返回一个Future对象,异步非阻塞式;

HystrixObservableCommand可以发出多个请求,返回一个结果

  • observe() — 返回Obervable对象,热执行
  • toObservable() — 返回Obervable对象,冷执行

热执行就是不管你事件有没有注册完(onCompleted(),onError,onNext这三个事件注册),就去执行我的业务方法即(HystrixObservableCommand实现类中的construct()方法)
冷执行就是,事件监听方法注册完成后,才执行业务方法

Hystrix的内部处理逻辑

在这里插入图片描述

  1. 构建Hystrix的Command对象, 调用执行方法.
  2. Hystrix检查当前服务的熔断器开关是否开启, 若开启, 则执行降级服务getFallback方法.
  3. 若熔断器开关关闭, 则Hystrix检查当前服务的线程池是否能接收新的请求, 若超过线程池已满, 则执行降级服务getFallback方法.
  4. 若线程池接受请求, 则Hystrix开始执行服务调用具体逻辑run方法.
  5. 若服务执行失败, 则执行降级服务getFallback方法, 并将执行结果上报Metrics更新服务健康状况.
  6. 若服务执行超时, 则执行降级服务getFallback方法, 并将执行结果上报Metrics更新服务健康状况.
  7. 若服务执行成功, 返回正常结果.
  8. 若服务降级方法getFallback执行成功, 则返回降级结果.
  9. 若服务降级方法getFallback执行失败, 则抛出异常.

参考

防雪崩利器:熔断器 Hystrix 的原理与使用

相关阅读

项目代码
SpringCloud 汇总【Greenwich 版】
SpringCloud(一):Eureka注册中心【Greenwich 版】
SpringCloud(二):Ribbon负载均衡【Greenwich 版】
SpringCloud(三):Feign声明式服务调用【Greenwich 版】
SpringCloud(四):Hystrix熔断器介绍【Greenwich 版】
SpringCloud(五):Hystrix的请求熔断与服务降级【Greenwich 版】
SpringCloud(六):Hystrix的请求合并【Greenwich 版】
SpringCloud(七):Hystrix仪表盘与Turbine集群监控【Greenwich 版】
SpringCloud(八):Zuul网关【Greenwich 版】
SpringCloud(九):Config配置中心【Greenwich 版】
SpringCloud(十):Bus消息总线【Greenwich 版】
SpringCloud(十一):Stream消息驱动 + RabbitMQ【Greenwich 版】
SpringCloud(十二):Sleuth链路跟踪【Greenwich 版】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值