Hystrix服务熔断
主要记录在本地搭建SpringCloud Demo时,使用Hystrix模拟服务降级和服务熔断的相关知识点和配置。
Hystrix断路器
1.使用场景
在微服务架构中,服务调用的链路会随着业务的复杂边的越来越长,一旦其中某些服务节点挂掉,就会导致整体链路无法继续进行。
服务雪崩:是一种因“服务提供者的不可用”(原因)导致“服务调用者不可用”(结果),并将不可用逐渐放大的现象。
比如在一个调用连上,服务A调用服务B,服务B调用服务C,如果此时流量突然激增,服务A和服务B能抗住请求,但是服务C挂了,那么请求都阻塞在服务B上,服务B的线程资源会被逐步消耗完,进而导致服务B也不可用,同理,最终服务A也会不可用。
服务熔断则是解决服务雪崩的方案之一。
2.服务降级
啥时服务降级?如果下游服务响应太慢,服务提供者会进行服务降级,如暂时停掉重要性低的服务来释放出服务器的资源,来保证主业务的可用性,增加服务响应速度;上游服务调用者发现下游服务响应速度太慢,可以在本地调用服务降级逻辑,直接返回给用户,给予用户友好提示,避免卡顿。
3.服务熔断
服务熔断是服务降级的一种方式。
当下游服务因为某种原因变得不可用或者响应过慢时,上游服务为了保证自身的可用性,不再继续调用下游服务,而是直接返回,快速释放线程资源。等待下游服务可用后,再逐步恢复调用。
4.Hystrix
Hystrix是一个用于处理分布式系统的延迟和容错的开源库。它提供了服务降级、服务熔断、监控等能力。
Hystrix的状态图如下图所示:
断路器共三个状态,开启、关闭和半开。服务正常时处于关闭状态,当服务调用的错误率达到设定的阈值时,会转变为开启状态。此时会定义一个reset timeout时间计时,过了这个时间后转换为半开状态,然后尝试调用之前异常的服务,如果服务调用成功后,就会恢复服务;如果调用失败,则重新计时。
检测到服务节点可以正常响应后,就会自动恢复调用链路。
Hystrix的工作流程图如下(官网地址):
图中蓝色箭头表示调用路径,红色表示响应路径
- 创建对象。首先创建HystrixCommand或者HystrixObserableCommand对象
- 执行命令。
- 查看缓存。如果当前请求开启了请求缓存,并且缓存命中,则将缓存结果以Observable对象的形式返回。
- 检查断路器状态。如果为打开,Hystrix直接转到Fallback处理逻辑,即第8步;如果状态为关闭,则检查服务的线程池或信号量状态。
- 检查服务的线程池或信号量状态。如果资源已经被占满,也会转到Fallback处理逻辑;如果有空闲的资源,则转到下一步。
- 根据第一步创建的对象,采取相应的方法去请求服务。HystrixCommand.run() :返回一个单一的结果,或者抛出异常。HystrixObservableCommand.construct(): 返回一个Observable 对象来发射多个结果,或通过 onError 发送错误通知。
- Hystrix会将调用的信息(成功、失败、拒绝超时等)反馈给断路器,断路器会维护一组计数器来统计这些信息。然后断路器根据这些信息来决定断路器的状态。
- 如果调用命令执行失败,断路器会进入fallback回退处理,即服务降级。从图中可以很容易看出,断路器打开状态、资源不足、服务调用失败和超时都会进入服务降级处理逻辑。
- 执行成功后,将处理结果直接返回或者以Observable的形式返回。
本地搭建相关配置
首先在主函数上添加@EnableHystrix
注解
服务的Service层的实现如下:
1 | // ------------------------------ 服务熔断 ----------------------------------- |
这里通过访问负数id来模拟服务的不可用,当服务调用失败率达到阈值65%时,就会开启服务熔断,进而调用paymentCircuitBreakerFallback方法。
本地的模拟效果如下,不断使用负数id进行调用,使得失败调用的比例上升,从而改变了断路器的状态,然后我们调用整数id,发现仍然进入了Fallback服务降级逻辑,因为此时断路器状态为open。
我们继续调用正确的id,当断路器经过休眠窗口计时,即10秒后,尝试再次调用服务,发现可以正常调用,则修改断路器的状态为close,之后服务能够正常调用。
Hystrix的监控Dashboard
配置比较简单,我们在本地使用9001端口,使用@EnableHystrixDashboard
注解,如下:
1 |
|
在服务端都需要添加坐标:
1 | <dependency> |
PS:这里在调试时可能检测不到(Unable to connect to Command Metric Stream/404),需要在服务端的主方法中添加如下配置:
1 | /** |
Dashboard的首页如下,需要填写监控的地址:
然后进入监控页面:
可以看到上图的断路器处于Open状态,图中的80%表示最后10秒服务调用的失败率,折线表示请求的变化率,下面一半表示Hystrix的线程池状态。