保护私人版权,尊重他人版权。转载请注明出处并附带页面链接
如何实现熔断机制
一、服务调用链
通过该时序图,我们可以看到:客户端(Client)发起了一次请求 Request1,网关(Gateway)在接收到请求后将它转发(标记为 Request2)给 Service-A;由于这次请求涉及 Service-B 中的数据,所以 Service-A 又向 Service-B 发起了一次 Request3 获取对应的数据;处理结束后,将结果返回给网关,由网关将结果返回给客户端。这里的 Request2 和 Request3 就共同组成了这次调用的调用链。
二、服务雪崩
服务雪崩是指当调用链的某个环节(特别是服务提供方服务)不可用时,将会导致其上游环节不可用,并最终将这种影响扩大到整个系统中,导致整个系统的不可用。如下图所示:
第一阶段是服务提供者不能用。 如上图所示,在初始阶段,一切运行良好,网关、Service-A 和 Service-B 可以响应客户端的各种请求。但在某一个时间节点,服务提供者 Service-B 由于网络故障或者请求过载不可用,而无法及时响应各类请求。
第二阶段是服务调用者不可用。在服务提供者不可用之后,客户端可能会因为错误提示或者长时间的阻塞而不断发送相同的请求到网关中,网关再次将请求转发给 Service-A 进行处理,Service-A 根据业务流程也向 Service-B 发起数据请求;同时,上一阶段中 Service-A 对 Service-B 超时或者失败的请求可能会因为 Service-A 中的重试机制再次请求 Service-B。但这些请求都无法从 Service-B 中获取到有效的返回,最坏的结果就是都被阻塞,无法及时响应。Service-A 会因为发起过多对 Service-B 的请求而逐渐累积一堆等待线程,耗尽线程池中的资源,从而无法响应其他请求,最终导致自身的不可用。
最后一阶段是整个系统的不可用。Service-A 中的等待请求同样阻塞了转发请求的网关。在多线程阻塞型的网关中,大量等待请求将会产生大量的阻塞线程,使得网关没有足够的资源处理其他请求,进而导致整个系统无法对外提供服务。
三、断路器
为了避免服务雪崩现象的出现,我们就需要及时“壮士断腕”,在必要的时候暂时切断对异常服务提供者的调用,以保证部分服务可用和整体系统的稳定性。
如上图所示,我们在 Serivce-A 向 Service-B 的请求中增加了一根“保险丝”——断路器。它统计一段时间内 Service-A 对 Serivice-B 请求的响应结果,在超时或者失败次数过多的情况下,阻断 Service-A 对 Service-B 的请求,直接返回相关的异常处理结果,使得 Service-A 中的请求线程能够及时返回,避免资源耗尽而不可用,从而保护了服务调用者和避免了服务级联失败。
断路器的三种状态:关闭,打开,半开关。
四、实现
golang:
https://studygolang.com/articles/11875
php: