题记与说明
| 元信息 | |
|---|---|
| 标题 | Timeouts, retries, and backoff with jitter |
| 作者 | Marc Brooker(AWS Senior Principal Engineer,Amazon Builders' Library) |
| 来源 URL | https://builder.aws.com/content/3EumjoZascWd1oZiEgL8ORlv3qE/timeouts-retries-and-backoff-with-jitter |
| 存档日期 | 2026-11-03 |
| 标签 | 分布式系统、容错设计、重试与退避、AWS、SRE、Agent 系统 |
这篇讲什么
远程调用必然失败,Amazon 的答案是三件套:超时(客户端最多等多久,防止资源被挂起的请求耗尽)、重试(利用故障的"部分性"和"瞬态性"救回请求)、退避 + 抖动(拉开重试间隔、打散重试时间,防止重试本身变成新的过载)。文章逐个讲清了每件工具的正确用法和踩坑方式。
核心观点
- 重试是"自私"的:客户端重试,本质是花服务器的资源换自己的成功率。故障是瞬态时这很划算;但故障若由过载引起,重试会放大负载、甚至拖慢恢复——"重试像一味猛药,剂量对了有用,过量就是伤害"。
- 多层重试会相乘:五层调用栈、每层 3 次重试,数据库一故障,负载瞬间放大 243 倍(3^5),几乎不可能恢复。最佳实践:只在调用栈的一个点重试。
- 熔断器不是银弹:它引入难以测试的模式切换行为,AWS 用 token bucket 做本地重试限流(2016 年起内置于 AWS SDK)——有令牌就随便重试,令牌耗尽就按固定速率重试。
- 抖动要加到所有定时器,且对周期任务用"一致的抖动"(同一主机每次产生同样的偏移)而非纯随机——这样故障会以固定模式复现,人类才能从模式中定位根因。
- 超时值怎么定:先接受一个误超时率(如 0.1%),再看下游对应分位数(p99.9)的延迟。
最值得记住的金句与数据
- "Retries are selfish." ——重试是客户端在宣示"我的请求更重要",要求服务为它多花资源;太自私的客户端会制造大范围故障。
- 243x:五层 × 每层 3 次重试 = 数据库故障时负载放大 243 倍。
- 0.1% / p99.9:用可接受的误超时率反查下游延迟分位数来定超时值。
对我的启发
写 Agent 系统时这条几乎可以照抄:Agent 的调用链(planner → subagent → tool → API)天然就是多层嵌套,LLM API 又经常 429 限流,正是文中"重试相乘 + 过载放大"的完美温床。落地三件事:只在最外层重试一次、指数退避封顶 + 抖动、用 token bucket 限速而不是裸熔断。另外,"一致的抖动便于排障"这个反直觉细节,比单纯"加随机数"高明得多。写作上也很值得学:一篇 2019 年的文章至今被反复引用,靠的就是把复杂权衡压缩成"重试是自私的"这样能被记住的句子。
适合谁读
后端/分布式工程师、SRE,以及所有在给 Agent 或工具调用链路写重试逻辑的 AI 应用开发者——这篇文章就是你重试策略的验收清单。