版权声明 本站原创文章 由 萌叔 发表
转载请注明 萌叔 | http://vearne.cc

1. 引言

提到熔断器,大家总会提到Hystrix.但是Hystrix似乎给人一种云里雾里的感觉. 前段时间,我维护的服务也增加了熔断机制,本文中,我将结合我自己的理解来谈谈熔断。

我们选择的是rubyist/circuitbreaker, 这个库的代码可读性比Hystrix以及afex/hystrix-go要高不少,也推荐一下。

2. 关于熔断

image_1dfg4f1smu5riuv1d88l5si83m.png-85.3kB

如上图所示,熔断器把客户端服务提供方隔离开来,在客户端调用服务提供方接口时,对服务提供方的服务质量进行监测。如果服务提供方出现问题,则将触发熔断。 这里引出了几个问题

问题1:什么样的情况,可以理解为服务提供方出现了问题?

问题2:触发熔断会怎么样?

问题3:熔断打开以后,如何关闭?

3. 熔断器与状态机

image_1dffq9md915vfaftok3cenjrs9.png-17.8kB
在熔断器内部有3种状态

1. Closed 熔断器关闭

客户端正常访问服务提供方

2. Open 熔断器打开

阻断客户端服务提供方的访问

3. Half Open 熔断器半开

熔断器开始重新判断是否需要继续熔断

熔断器只是简单在状态机的状态之间切换,至于熔断之后,如何处理客户端的请求,*则是更上层业务代码的事情

结合rubyist/circuitbreaker,我来谈谈状态之间的装换条件

3.1 Closed -> Open

服务提供方出现异常
1) 连续发生threshold个错误,立即熔断(ConsecutiveTripFunc)
2)单位时间请求数达到minSamples个,错误率达到rate,即熔断(RateTripFunc)
3)单位时间发生threshold个错误,立即熔断(ThresholdTripFunc)

这里的错误完全是由业务系统来定义,可能是
a) 后端接口的响应严重超时
b) 后端服务返回异常的错误(如HTTP协议 5xx)
c) RPC返回有异常的错误码

当熔断器处于Open状态,客户端服务提供方的访问被阻断了。我们该如何响应客户端的请求?
通常而言,可以有这么几种做法
1. 直接返回给客户端失败信息
2. 将返回降级后的结果
比如针对读请求,可以返回固定值,或者cache中的历史数据

3.2 Open -> Half Open

在熔断一段时间后,服务提供方的服务可能已经恢复了。那么怎么感知到服务提供方的服务已经恢复。
rubyist/circuitbreaker的做法是使用定时器
(2种实现,ExponentialBackOff和ConstantBackOff),每当定时器的设定的时间到达,熔断器的状态从Open 切换到 Half Open

3.3 Half Open -> Closed / Half Open -> Open

Half Open状态,熔断器重新探测(计算)服务提供方的健康情况进行检测。

如果服务提供方的服务已经恢复,则熔断器切换到Closed状态,否则切换到Open

4 总结

最后我们来聊聊熔断的好处。如果服务提供方已经过载,比如响应超时严重,继续对它进行请求,可能会使得客户端因超时而请求失败。客户端因为失败可能会执行多次重试,这种重试反而极有可能压垮服务提供方
另外严重的超时还会影响用户的体验,而fail fast,适当的降级,可以提高用户的整体体验。

参考资料

  1. CircuitBreaker

如果我的文章对你有帮助,你可以给我打赏以促使我拿出更多的时间和精力来分享我的经验和思考总结。

微信支付码

1 对 “从状态机看熔断器”的想法;

发表评论

电子邮件地址不会被公开。

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据