微服务-熔断降级

为什么需要熔断

在微服务中服务间依赖非常常见,比如评论服务依赖审核服务,审核服务又依赖反垃圾服务。而当审核服务调用反垃圾服务是,反垃圾服务由于自身问题导致审核服务逻辑一直等待,而这个时候评论服务又在一直调用审核服务,审核服务就有可能因为堆积了大量请求而导致服务宕机,造成服务雪崩。

image.png

那么针对这种情况,我们要如何解决呢。我们可能第一想到的就是,重试。但在这种情况下,重试不一定合适。重试是为了应付偶尔抖动的情况,以求更多地挽回损失,但如果反垃圾服务是down掉了,或者是反垃圾服务超负载导致调用超时,重试反而会导致问题加剧。那么现在就需要使用熔断机制来保护我们的服务了。

tip:一个服务作为调用方调用另一个服务时,为了防止被调用服务出现问题,进而导致服务调用方出现问题,所以服务调用方需要进行自我保护,而保护的常用手段就是熔断。

熔断的原理

image.png

在这种模式下,服务调用方为每一个调用服务 (调用路径) 维护一个状态机,在这个状态机中有三个状态:

关闭 (Closed):在这种状态下,我们需要一个计数器来记录调用失败的次数和总的请求次数,如果在某个时间窗口内,失败的失败率达到预设的阈值,则切换到断开状态,此时开启一个超时时间,当到达该时间则切换到半关闭状态,该超时时间是给了系统一次机会来修正导致调用失败的错误,以回到正常的工作状态。在关闭状态下,调用错误是基于时间的,在特定的时间间隔内会重置,这能够防止偶然错误导致熔断器进去断开状态

打开 (Open):在该状态下,发起请求时会立即返回错误,一般会启动一个超时计时器,当计时器超时后,状态切换到半打开状态,也可以设置一个定时器,定期的探测服务是否恢复

半打开 (Half-Open):在该状态下,允许应用程序一定数量的请求发往被调用服务,如果这些调用正常,那么可以认为被调用服务已经恢复正常,此时熔断器切换到关闭状态,同时需要重置计数。如果这部分仍有调用失败的情况,则认为被调用方仍然没有恢复,熔断器会切换到关闭状态,然后重置计数器,半打开状态能够有效防止正在恢复中的服务被突然大量请求再次打垮。

常见的有三种熔断降级策略

  • 错误比例:在所设定的时间窗口内,调用的访问错误比例大于所设置的阈值,则对接下来访问的请求进行自动熔断。
  • 错误计数:在所设定的时间窗口内,调用的访问错误次数大于所设置的阈值,则对接下来访问的请求进行自动熔断。
  • 慢调用比例:在所设定的时间窗口内,慢调用的比例大于所设置的阈值,则对接下来访问的请求进行自动熔断。

服务降级

当下游的服务因为某种原因响应过慢,下游服务主动停掉一些不太重要的业务,释放出服务器资源,增加响应速度。

关于降级,这里有两种场景:

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

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

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

总结

调用端可以通过熔断机制进行自我保护,防止调用下游服务出现异常,或者耗时过长影响调用端的业务逻辑,很多功能完整的微服务框架都会内置熔断器。其实,不仅微服务调用之间需要熔断器,在调用依赖资源的时候,比如 mysql、redis 等也可以引入熔断器的机制。

参考资料
https://www.136.la/au/show-5018.html
https://www.cnblogs.com/phyger/p/14048571.html

你可能感兴趣的:(微服务-熔断降级)