服务雪崩、熔断、降级和限流

服务雪崩

一条服务调用链路,服务 A 调 服务 B ,服务 B 调 服务 C,如果服务 C 调用失败,那么服务 B 的请求会阻塞,慢慢的,服务 B 会变得不可用,接着,服务 A 也会不可用。

一个服务失败,导致整条链路的服务都失败的情形,我们称之为「 服务雪崩 」。

解决服务雪崩的手段有「 服务熔断 」和「 服务降级 」。

服务熔断

服务熔断:当下游服务因访问压力过大而响应变慢或失败,上游服务为了保护系统整体的可用性,可以暂时切断对下游服务的调用,直接返回,快速释放资源。如果目标服务情况好转则恢复调用。

目前熔断器有,阿里出的 Sentinel,Netfilx 的 Hystrix 和 基于 Hystrix 实现的 Spring Cloud Hystrix。

熔断设计 三个模块:熔断请求判断算法、熔断恢复机制、熔断报警

熔断请求判断算法

使用无锁循环队列计数,每个熔断器默认维护 10 个 bucket,每 1 秒一个 bucket,每个 blucket 记录请求的成功、失败、超时、拒绝的状态,默认错误超过 50% 且 10 秒内超过 20 个请求进行中断拦截。

熔断恢复机制

对于被熔断的请求,每隔 5s 允许部分请求通过,若请求都是健康的(RT<250ms)则对请求健康恢复。

熔断报警

对于熔断的请求打日志,异常请求超过某些设定则报警。

熔断器的状态

  • 最开始,服务没有故障时,熔断器处于 closed 状态

  • 在固定时间内(Hystrix 默认是 10 秒),接口调用出错比率达到一个阈值时( Hystrix 默认为 50%),会进入熔断开启状态。进入熔断状态后,后续对该服务接口的调用不再经过网络,直接执行本地的 fallback 方法

  • 在进入熔断开启状态一段时间之后(Hystrix 默认是 5 秒),熔断器会进入 half-open 半熔断状态。所谓半熔断就是尝试恢复服务调用,允许有限的流量调用该服务,并监控调用成功率。如果成功率达到预期,则说明服务已恢复,进入熔断关闭状态;如果成功率仍旧很低,则重新进入熔断开启状态。

  • 在尝试一段时间后,服务还没有恢复,则进入本地的服务降级的逻辑处理。

参考: 漫画:什么是服务熔断?

服务降级

当服务器压力剧增的情况下,为了保证重要或基本的服务能正常运行,选择性的将一些 不重要不紧急 的服务或任务进行服务的 延迟使用暂停使用,为了保证功能的可用性,调用本地的一些降级逻辑处理。

服务降级要考虑的问题:

  • 核心和非核心服务

  • 是否支持降级,降级策略

  • 业务放通的场景,策略

降级分类

降级按照是否自动化可分为:自动开关降级和人工开关降级。

降级按照功能可分为:读服务降级、写服务降级。

降级按照处于的系统层次可分为:多级降级。

降级策略

  • 限流降级
  • 熔断降级
  • 页面拒绝服务:页面提示由于服务繁忙此服务暂停
  • 延迟持久化:页面访问照常,但是涉及记录变更,会提示稍晚能看到结果,将数据记录到异步队列或 log,服务恢复后执行。

降级与熔断区别是什么?

  • 触发原因不太一样,服务熔断一般是某个服务(下游服务)故障引起,而服务降级一般是从整体负荷考虑。
  • 熔断可以理解为实现服务降级的一种手段。进入熔断状态后,后续对该服务接口的调用不再经过网络,直接执行本地的默认方法,达到服务降级的效果。

如何实现自动降级?

  • 超时降级:主要配置好超时时间和超时重试次数和机制,并使用异步机制探测恢复情况。

  • 失败次数降级:主要是一些不稳定的 API,当失败调用次数达到一定阀值自动降级,同样要使用异步机制探测恢复情况。

  • 故障降级:如要调用的远程服务挂掉了(网络故障、DNS 故障、HTTP 服务返回错误的状态码和 RPC 服务抛出异常),则可以直接降级。

  • 限流降级:当触发了限流超额时,可以使用暂时屏蔽的方式来进行短暂的屏蔽。

参考:微服务架构—服务降级

服务限流

系统规定了多少承受能力,只允许这么些请求能过来,其他的请求直接拒绝。

一般限制的指标有:请求总量或某段时间内请求总量

  • 请求总量:比如秒杀的,秒杀 100 份产品,我就放 5000 名进来,超过的直接拒绝请求了。
  • 某段时间内请求总量:比如规定了每秒请求的峰值是 1W,这一秒内多的请求直接拒绝了。

解决方案

  • 排队等待
  • 拒绝响应:如前端返回静态页面,当前访问用户过多,请稍后再试

优点

在高并发中,限流是很重要的手段,可以防止服务器资源无节制的扩容,同时可以避免系统崩溃。

缺点

用户体验不好

使用 Hugo 构建
主题 StackJimmy 设计