Fork me on GitHub

版权声明 本站原创文章 由 萌叔 发表
转载请注明 萌叔 | https://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 对 “从状态机看熔断器”的想法;

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注