知识卡片

重试模式的四个前提条件及多层嵌套导致的请求数指数放大

普通读书笔记卡

内容

[[七种容错策略分为事后弥补与事前保险两大类]]里故障转移和故障恢复的共同 实现基础都是”重试”,重试模式只适合解决瞬时故障(网络抖动、临时过载 503这类有可能自愈的失灵),实现本身不难,真正的风险在于滥用。应同时 满足四个前提才该重试:只在主路逻辑的关键服务上做同步重试,非关键服务 不首选重试;只对瞬时故障重试(401这类说明服务本身可用只是无权限的 错误,重试毫无意义);只对幂等服务重试(RESTful语义下GET/HEAD/PUT/ DELETE通常可视为幂等,POST通常不是);必须有明确终止条件(超时终止 +次数终止两种,通常最多2~5次,且应尊重服务端返回的Retry-After)。真正 的隐患在于重试可以在链路的多个环节各自独立实现——客户端、网关、负载 均衡器都可能配置了重试——这些重试次数会以乘积而非加和的方式叠加。书中 给出的具体例子:一套基于Netflix OSS的系统如果同时在Zuul、Feign、Ribbon 上都开了4次重试(Ribbon还能转移4个服务副本),且不考虑超时提前终止, 理论最大调用次数是4×4×4×4=256次——这个数字远超大多数程序员的直觉 预期,也是重试模式”看似简单却容易失控”的核心原因。

参考来源

- 位置:《凤凰架构:构建可靠的大型分布式系统》第8章"流量治理"8.1.2节 "容错设计模式"(源文件:_epub-src对应OEBPS/Text/chapter99.xhtml) - 结论依据:原文列举重试模式应满足的四个前提条件(主路关键服务/瞬时 故障/幂等服务/明确终止条件),并用Zuul+Feign+Ribbon三层各自重试4次、 Ribbon再转移4个副本的例子算出最多256次调用,直接支撑本卡片结论。 - 原始内容:假设它们都重试4次,且Ribbon可以转移4个服务副本来计算, 理论上最多会产生高达4×4×4×4=256次调用请求……对于没有太多经验的 程序员,有可能根本意识不到其中会带来多大的负担。