0%

微服务治理之降级、限流、熔断

限流

C⇄S 的异常问题:C的请求太多,超出S的服务能力,导致S不可用。DoS攻击就是根据此原理,耗尽被攻击对象的资源,让目标系统无法响应甚至崩溃。解决方案:S对C限流,保护S的服务资源。

限流通常在网关或网络层面实施。对各类请求设置最高的QPS阈值,当请求高于阈值时直接阻断。常用的限流算法有滑动计数,漏斗限流和令牌桶限流三种。

  • 滑动计数限流

按时间片(比如1秒)定义滑动窗口,计数器记录当前窗口的请求次数,达到阈值就限流,窗口滑动后计数器归零。可采用循环队列数据结构实现。

  • 漏斗限流

维护一个队列,所有请求进队列,按FIFO服务,队满溢出则丢弃请求。

  • 令牌桶限流

按固定速率往桶中存入令牌,服务前先从桶中取令牌,取到令牌才服务。

降级

C⇄S的异常问题:S自身出现异常,或者由于资源有限需要对部分C请求故意表现为异常(类似限流),为了不影响其他服务功能,主动关闭服务的一些功能。

降级的反义词是升级,升级需要代码开发,降级类似于把部分代码注释掉,牺牲部分功能。这要求S在实现时,需要具备感知异常的能力,并对关键逻辑实现开关控制。实际场景中,对异常的『感知』通常由熔断器实现。

熔断

C⇄S的异常问题:C发现S出现异常(比如大量超时),主动出击,暂停对S的请求。

C对S熔断后,那么原本需要调用S实现的逻辑怎么办呢?可以用mock数据、缓存数据、缺省数据等替代,或者干脆就是抛异常返回错误信息。此时,如果C也是一个服务,它相当于做了服务降级。所以我们经常看到服务熔断和服务降级一起出现(Hystrix的断路器在实现时就是把熔断和降级方案打包实现的)。但本质上它们不是一回事,降级发生在S,熔断发生在C。之所以配合实现,是因为许多微服务模块同时承担C和S两种角色。

熔断的设计有两个关键点:① 判断何时熔断,② 何时从熔断状态恢复。

判断何时熔断:通常使用无锁循环队列计数来实现。C对每次请求S的正常、异常(失败、拒绝、超时)返回计数,当异常返回次数超过设定阈值时进行熔断。

何时从熔断状态恢复:处于熔断状态时,C每隔一段时间(比如5秒),允许部分请求通过,若这部分请求正常返回,就恢复熔断。

layicr 微信

微信

layicr 支付宝

支付宝