雪崩效应
在微服务系统中,整个系统是以一系列功能独立的微服务组成,如果某一个服务,因为流量异常或者内部其他原因,导致响应异常,那么该服务会影响到其下游服务, 从而发生一系列连锁反应,最终导致整个系统崩溃,这就是微服务中的
雪崩效应
。例如:当前系统中有
A
,B
,C
三个服务,服务 A
是上游,服务 B
是中游,服务 C
是下游。 一旦下游服务 C
变得不可用,积压了大量请求,服务 B
的请求也随之阻塞,资源逐渐耗尽,使得服务 B
也变得不可用。 最后,服务 A
也变为不可用,整个系统链路崩溃。
熔断
熔断
机制是微服务调用链路中的的自我保护机制,当链路中某个服务响应时间过长甚至不可用时,会进行服务 熔断
,快速返回错误响应,停止 级联故障
,避免 雪崩效应
。熔断、限流、降级区别
限流
是针对服务请求数量的一种自我保护机制,当请求数量超出服务负载时,自动丢弃新的请求,是系统高可用架构的第一步。 服务有了 限流
之后,为什么还需要 熔断
呢? 限流
面向的是上游的服务,而 熔断
面向的是下游的服务。降级
通过将不重要的服务暂停,提高系统负载能力。例如电商的 秒杀
场景中,可以暂停 用户好友关系
, 用户信息
等服务。ㅤ | 触发条件 | 面向目标 |
熔断 | 下游服务不可用 | 下游 |
降级 | 服务自身负载高 | 自身 |
限流 | 上游服务请求多 | 上游 |
hystrix-go
三个状态
状态 | 说明 |
关闭 | 熔断关闭时所有的请求都会被接收 |
开启 | 熔断开启时所有的请求都会被拒绝 |
半打开 | 熔断开启时一段时间之后,尝试接收一个请求,确定下游服务是否已恢复,如果这个请求正常返回,熔断自动关闭状态,否则熔断回退到开启状态 |

这里需要注意的是: afex/hystrix-go 的实现中并没有
半打开
的状态,也就是说,一旦 熔断
开启后, 只能等待配置的时间之后,才能去主动判定下游服务是否已经恢复,继而恢复请求。笔者认为这个不是重要的部分,如果读者比较介意的话, 可以参考 引用部分 的另外两个 熔断
开源组件。示例代码
主流程代码
主流程代码逻辑描述
我们通过修改
hystrix
的默认配置,期望达到以下的熔断效果:- 前两个请求直接返回错误
- 此时错误百分比达到
100%
, 但是还未达到开启熔断
的最小请求数量 (5)
- 继续发出请求,接下来的
3
个请求全部成功,此时请求数量达到开启熔断
的最小请求数量
- 开启
熔断
- 继续发出请求,接下来的
5
个请求全部返回fallback error
, 同时每次请求之间间隔0.1 秒
- 此时达到开启
熔断
后,重试服务是否恢复的等待时间 (0.5 秒)
- 继续发出请求,接下来的
5
个请求全部成功
运行测试
通过测试的数据结果,我们可以看到,
熔断
执行流程和上面描述的逻辑一致,接下来,我们研究一下 hystrix-go
的内部实现。算法实现
熔断配置对象
各字段代表的含义,请参照刚才示例代码中的注释。
创建熔断配置
ConfigureCommand
方法根据参数创建一个 熔断
配置对象,如果对象中的某些字段参数未提供,则适用默认值替代。熔断器对象
CircuitBreaker
表示单个请求对应的 熔断器
对象,对象可以验证请求是否触发了 熔断
机制,以及是否应该拒绝该请求继续访问。GetCircuit 函数
GetCircuit
函数根据名称返回对应的 熔断器
对象以及该名称函数调用是否触发了 熔断
机制。Do 函数
Do
函数以阻塞的方式运行参数函数,直到函数返回成功或者错误 (包括触发了熔断),具体的执行工作是由 DoC
函数和 GoC
函数完成的。DoC 函数
DoC
函数负责参数的执行前封装工作,Goc
函数负责参数的具体执行工作。GoC 函数
GoC
运行参数函数,同时跟踪该函数历史运行情况。如果参数函数触发了 熔断
开启,则必须等待服务恢复。Do 函数调用链路

最后,我们来看一下
熔断
开启与状态判断机制的内部实现。AllowRequest 方法
AllowRequest
方法在具体的请求执行之前,先判断 熔断
是否已经开启,当 熔断
开启时,熔断
时间超过等待外部服务恢复时间时返回 ture
。IsOpen 方法
IsOpen
方法在具体的请求执行之前,根据 熔断
是否以开启确定是否已经拒绝请求执行。allowSingleTest 方法
allowSingleTest
方法判断 熔断
时间是否已经超过重试服务是否恢复的等待时间。通过上面三个方法实现代码可以看到:
熔断
开启与状态判断是每次请求到来时实时判断的。
小结
本文描述了
熔断
的基本概念以及 熔断
和 限流
、降级
之间的区别,同时借助开源的 afex/hystrix-go 组件源代码, 研究了如何使用 Go
语言实现一个 熔断器
组件,感兴趣的读者可以阅读下列文章,了解下其他开源 熔断器
组件是如何实现的。Reference

转载申请
本作品采用 知识共享署名 4.0 国际许可协议 进行许可,转载时请注明原文链接,图片在使用时请保留全部内容,商业转载请联系作者获得授权。