RPC 系列(四十二):从雪崩看限流

“雪崩”指的是访问服务集群时绝大部分请求都超时,且在流量减少时仍无法恢复的现象。下面解释这个现象的来源。

单一服务:过载但可恢复

当流量超出服务的最大 qps 时,服务将无法正常服务;当流量恢复正常时(小于服务的处理能力),积压的请求会被处理,虽然其中很大一部分可能会因为处理得不及时而超时,但服务本身一般还是会恢复正常的。这就相当于一个水池有一个入水口和一个出水口:如果入水量大于出水量,水池子终将盛满,多出的水会溢出来;但如果入水量降到出水量之下,一段时间后水池总会排空。

雪崩并不是单一服务能产生的。

多级服务:拥塞的传递

如果一个请求经过两个服务,情况就有所不同了。比如请求访问 A 服务,A 服务又访问了 B 服务。当 B 被打满时,A 处的 client 会大量超时。如果 A 处的 client 在等待 B 返回时也阻塞了 A 的服务线程(常见),且使用了固定个数的线程池(常见),那么 A 处的最大 qps 就从「线程数 / 平均延时」降到了「线程数 / 超时」。由于超时往往是平均延时的 3 至 4 倍,A 处的最大 qps 会相应地下降 3 至 4 倍,从而产生比 B 处更激烈的拥塞。如果 A 还有类似的上游,拥塞会继续传递上去。

但这个过程还是可恢复的:B 处的流量终究由最前端的流量触发,只要最前端的流量回归正常,B 处的流量总会慢慢降下来,直到能正常回复大多数请求,从而让 A 恢复正常。当然也存在一些例外情况会阻碍这种自恢复。

了解这些因素后,可以更好地理解 brpc 中相关的设计。

brpc 用户如何防止雪崩

对于 brpc 的用户来说,要防止雪崩,主要注意两点:

  • 不要让请求在服务端排队:把请求积压在队列中等着处理,并不能提高服务的吞吐;积压的请求大概率已经超时,处理它们只是白白消耗服务端的资源,反而恶化拥塞。与其排队,不如通过设置最大并发让多余的请求尽快被拒绝。
  • 尽快取消:当 client 超时或已经离开时,应当尽快取消尚未处理的请求,避免继续占用本服务与下游的资源,让系统能腾出处理能力服务还有效的请求。

注意:雪崩的本质是过载之后资源被无效请求持续占用。限流(限制最大并发、自适应限流)的出发点正在于此:与其让所有请求一起变慢,不如主动放弃一部分,保住服务的处理能力。

系列导航


   转载规则


《RPC 系列(四十二):从雪崩看限流》 由 吴杭沉 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
RPC 系列(四十三):ExecutionQueue 详解 RPC 系列(四十三):ExecutionQueue 详解
类似于 kylin 的 ExecMan,bthread::ExecutionQueue 提供了异步串行执行的功能。ExecutionQueue 的相关技术最早使用在 RPC 中实现多线程向同一个 fd 写数据,在 r31345 之后加入到了
2024-06-25
下一篇 
RPC 系列(四十一):自适应并发限流 RPC 系列(四十一):自适应并发限流
服务的处理能力是有客观上限的。当请求速度超过服务的处理速度时,服务就会过载。如果服务持续过载,会导致越来越多的请求积压,最终所有的请求都必须等待较长时间才能被处理,从而使整个服务处于瘫痪状态。 与之相对的,如果直接拒绝掉一部分请求,反而能够
2024-06-11
  目录