跳到主要内容
约 4 分钟2 张卡

重试

重试用于恢复短暂故障,也会增加下游负载。本文负责错误分类、退避与重试预算。

1. 面试核心​

先记住这几条,再读正文
  • 多层放大。 多层各尝试 3 次时,四层最深调用上界为 3⁴=81 次。卡 · 可重试错误
  • 退避抖动。 Full jitter 在当前指数退避上限内随机选择等待时间。
  • 重试预算。 单请求次数与系统级重试预算共同约束额外负载。
  • 服务端等待建议。 Retry-After 支持秒数与 HTTP 日期,等待仍需服从总预算。卡 · Retry-After 与剩余预算
  • 并行备份请求。 Hedging 并行发送备份请求,消耗额外容量。

2. 可重试错误​

短暂连接错误与部分服务端错误可作为候选。参数错误、权限不足和确定性代码错误应直接失败。

是否重试还取决于接口语义与结果是否已提交。超时只能说明结果未知。持续过载时,继续发送会延迟恢复。

3. 写操作重试​

写请求需明确重复副作用边界。稳定请求标识与结果恢复见幂等键。

协议声明为幂等的方法,也需实现对应语义。POST 可以通过业务幂等契约支持安全重发。

4. 指数退避​

退避上限随失败次数增长,再受 cap 截断。

a = 0 表示第一次重试
backoff = min(cap, base × 2^a)

例如 base 为 100 ms,cap 为 1 s。前三次重试上限为 100、200、400 ms。退避等待也计入请求总预算。

5. 抖动​

无抖动退避会使大量客户端同步醒来。Full jitter 从 [0, backoff] 采样等待时间。

实例需避免使用相同随机序列或固定整秒调度。仅有随机等待仍需限制总次数和额外流量。

6. 尝试次数​

总尝试 3 次表示首次调用加两次重试。配置与指标应明确是否包含首次调用。

四层各尝试 3 次时,最深调用上界是 3⁴=81。总时限与提前成功会减少实际次数,但过载时仍需防放大。

选择一层承担主要业务重试。其他层仅保留语义明确的局部恢复。

7. 重试预算​

单请求上限无法控制全系统额外流量。重试预算可以约束总重试比例或并发数。

例如成功请求补充 retry token,重试消耗 token。错误持续时额度耗尽,请求快速失败。预算按下游或路由统计,避免一个故障耗尽全部配额。

8. Hedged request​

Hedging 在首个请求变慢后,并行发送备份请求。它适合有独立副本与额外容量的幂等读取。

首个可接受成功结果返回后,取消剩余尝试。取消仍需下游配合。整体过载时新增备份会进一步消耗容量。

应限制 hedging 比例与并发,并观测真实放大倍数。

9. 故障注入验证​

注入 reset、延迟、限流和局部实例故障。分别统计原始请求、attempt、成功率和 P99。

还需检查全体过载时预算是否停止追加请求。关闭重试后若系统恢复,应复查放大路径。取消后的在途数量也属于验收指标。

10. Retry-After 与剩余预算​

Retry-After: 2 表示等待 2 秒。HTTP 日期形式表示可以再次尝试的时间点。

客户端将服务端建议与本地退避共同纳入计划。一种策略是至少等待两者较大值,再加入有限抖动。日期形式还需考虑时钟偏差与解析失败。

例如总预算只剩 500 ms,而建议等待 2 秒。此时应结束自动重试,并返回明确结果。为赶 deadline 提前发送会破坏服务端的恢复节奏。

11. 常见问题​

11.1 5xx 的重试条件​

5xx 只是服务端错误类别。确定性缺陷、资源过载和短暂故障需要分别处理。仅有状态码不足以证明下一次尝试有价值。

11.2 实例切换与副作用​

12 · 面试题卡片​

12.1 为什么重试会形成流量放大,如何控制​

出现公司:字节跳动

考察重点

  • 理解瞬时与永久错误、幂等和结果未知。
  • 理解指数退避、full jitter 与端到端 deadline。
  • 理解多层重试乘法和系统级重试预算。

相关内容:可重试错误至故障注入验证。

参考回答

多层重试让最深下游的尝试数相乘。

四层各尝试 3 次,上界达到 81 次。下游过载时,额外请求会占用更多资源。

主要重试集中在一层,并限制总尝试数。指数退避与 jitter 分散时间,系统预算约束总量。所有等待与尝试共用 deadline。故障注入时分别统计原始请求与实际 attempt。

12.2 收到 Retry-After: 2,但请求只剩 500 ms,应该怎样处理?​

出现公司:暂无已核验的公开来源(本站自测)

考察重点:服务端等待建议与请求总时限。

相关内容:Retry-After 与剩余预算。

参考回答

结束本次自动重试,因为剩余预算无法覆盖建议等待。

Retry-After: 2 表示等待 2 秒。新尝试还需留出执行和返回时间。结果未知的写操作可提供状态查询入口。

13. 参考资料​