服务熔断降级限流

针对下面的情形,如图所示

43_服务熔断降级.png

当 Service A 调用 Service B,失败多次达到一定阀值,Service A 不会再去调 Service B,而会去执行本地的降级方法!对于这么一套机制:在 Spring cloud 中结合 Hystrix,将其称为熔断降级!

服务雪崩

我们从服务雪崩开始讲起!假设存在如下调用链:

44_服务熔断降级.png

而此时,Service A 的流量波动很大,流量经常会突然性增加!那么在这种情况下,就算 Service A 能扛得住请求,Service B 和 Service C 未必能扛得住这突发的请求。

此时,如果 Service C 因为抗不住请求,变得不可用。那么 Service B 的请求也会阻塞,慢慢耗尽 Service B 的线程资源,Service B 就会变得不可用。紧接着,Service A 也会不可用,这一过程如下图所示:

45_服务熔断降级.png

如上图所示,一个服务失败,导致整条链路的服务都失败的情形,我们称之为服务雪崩。那么,服务熔断和服务降级就可以视为解决服务雪崩的手段之一。

服务熔断

在分布式环境下,特别是微服务结构的分布式系统中, 一个软件系统调用另外一个远程系统是非常普遍的。这种远程调用的被调用方可能是另外一个进程,或者是跨网路的另外一台主机, 这种远程的调用和进程的内部调用最大的区别是,远程调用可能会失败,或者挂起而没有任何回应,直到超时。

更坏的情况是, 如果有多个调用者对同一个挂起的服务进行调用,那么就很有可能的是一个服务的超时等待迅速蔓延到整个分布式系统,引起连锁反应, 从而消耗掉整个分布式系统大量资源。最终可能导致系统瘫痪。断路器(Circuit Breaker)模式就是为了防止在分布式系统中出现这种瀑布似的连锁反应导致的灾难。

46_服务熔断降级.png

上图是断路器(Curcuit Breaker)的结构,它有两个基本状态(close和open)和一个基本 trip 动作:

  • close 状态下, client 向 supplier 发起的服务请求, 直接无阻碍通过断路器, supplier 的返回值直接由断路器交回给 client。
  • open 状态下,client 向 supplier 发起的服务请求后,断路器不会将请求转到 supplier, 而是直接返回 client, client 和 supplier 之间的通路是断的。
  • trip: 在 close 状态下,如果 supplier 持续超时报错, 达到规定。

47_服务熔断降级.png

上图是断路器的 扩展模式。

基本的断路器模式下,保证了断路器在 open 状态时,保护 supplier 不会被调用, 但我们还需要额外的措施可以在 supplier 恢复服务后,可以重置断路器。一种可行的办法是断路器定期探测 supplier 的服务是否恢复, 一但恢复, 就将状态设置成 close。断路器进行重试时的状态为半开(half-open)状态。

服务降级

那么,什么是服务降级呢?这里有两种场景:

  • 当下游的服务因为某种原因响应过慢,下游服务主动停掉一些不太重要的业务,释放出服务器资源,增加响应速度!
  • 当下游的服务因为某种原因不可用,上游主动调用本地的一些降级逻辑,避免卡顿,迅速返回给用户!

其实乍看之下,很多人还是不懂熔断和降级的区别!其实应该要这么理解:

  • 服务降级有很多种降级方式!如开关降级、限流降级、熔断降级!
  • 服务熔断属于降级方式的一种!

可能有的人不服,觉得熔断是熔断、降级是降级,分明是两回事啊!其实不然,因为从实现上来说,熔断和降级必定是一起出现。因为当发生下游服务不可用的情况,这个时候为了对最终用户负责,就需要进入上游的降级逻辑了。因此,将熔断降级视为降级方式的一种,也是可以说的通的!