← 返回题目列表

什么是重试预算?为什么要限制重试?

中等 第 23 / 26 题 更新于 2026/09/30
重试预算重试风暴退避幂等
学习 AI 实战项目

简化版

重试预算限制一段窗口内“额外尝试”相对原始请求的比例或绝对数量,防止下游故障时重试流量反过来压垮系统。 预算之外不再同步重试,而是快速失败、降级或进入异步恢复;预算必须与 deadline、错误类型、幂等性和调用层级一起设计。

详细版

可定义 retryRatio = retryAttempts / originalRequests,例如窗口内最多 10%,同时设置最低令牌避免低流量接口完全不能重试。只有连接建立失败、限流提示可重试等瞬态错误才消耗预算;参数错误和明确业务拒绝不重试。

每次重试采用指数退避加抖动,且必须落在剩余 deadline 内。多层 RPC 只允许靠近失败点的一层负责重试,避免三层各重试 2 次形成最多 27 次尝试。监控原始流量、额外尝试、预算耗尽、重试成功率与放大倍数。

完整版教学

一、为什么成功率优化会变成流量攻击

重试对偶发丢包有效,但对持续过载有害。1000 QPS 若每次最多重试 2 次,最坏可变成 3000 次下游调用;更多调用又提高超时,形成正反馈。重试预算把“提高成功率”的成本限制在系统可承担范围内。

心法:重试不是免费的第二次机会,而是从故障期稀缺容量里再买一次尝试。

二、预算的两种表达

ratioBudget = originalRequests × 10%
1000 原始请求 -> 最多 100 次额外尝试

retryAmplification = totalAttempts / originalRequests
1100 / 1000 = 1.10

比例预算随流量增长,绝对预算可保护固定容量。实际可同时限制“10% 且每秒不超过 200”,并给低流量窗口 5 个最小令牌,避免分母太小导致不可用。

三、哪些错误值得重试

结果是否重试原因
连接建立失败可服务端大概率未执行
HTTP 503/429按 Retry-After瞬态过载,需退避
读超时谨慎服务端可能已执行
参数错误否再试结果不变
余额不足否正常业务拒绝

有副作用请求还必须携带幂等键。超时后的写请求结果未知,盲目换节点重试可能重复扣款。

四、退避、抖动与 deadline

指数退避可取 100ms、200ms、400ms,并在每档加入随机抖动,避免大量客户端同一时刻醒来。请求总 deadline 为 500ms、首次调用已花 380ms 时,就不应再安排 400ms 重试。每次尝试的 timeout 也必须小于剩余预算。

remaining = deadline - now
if remaining < minAttemptTime + backoff:
    stop retrying

五、多层调用的乘法风险

网关调用 A,A 调 B,B 调 C;若每层都是“首次+2次重试”,最坏到 C 的尝试数是 3×3×3=27。通常只让最靠近失败依赖、最了解幂等语义的一层重试,上层用整体 deadline 和熔断保护。跨层还可传播 attempt 信息,禁止重复策略。

对冲请求也消耗预算。它在尾延迟高时并发发第二份请求,虽不是失败后再试,仍增加下游工作量。

六、预算令牌与观测

实现上可用滚动窗口或令牌桶:原始请求按比例补充重试令牌,每次额外尝试消耗一个。预算应按下游和操作隔离,不能让非核心查询耗完支付查询的令牌。配置修改先观察影子消耗,再灰度比例。

关键指标包括 original_requests、retry_attempts、budget_denied、retry_success、amplification 与按 attempt 的延迟。重试后成功率高但总 P99 超过用户 deadline,也不是有效收益。

七、常见误区与追问

  • 误区:每次最多重试两次已经足够安全。 高 QPS 与多层调用下仍会产生巨大放大。
  • 误区:所有超时都可以重试。 写超时可能已经产生副作用,需要幂等与结果查询。
  • 误区:固定间隔重试更可预测。 同步重试会造成惊群,应退避并加抖动。
  • 误区:对冲请求不算重试。 它同样消耗下游容量,应计入额外尝试预算。
  • 追问:预算耗尽后怎么办? 快速失败、降级或异步恢复,不能绕过预算换线程继续试。
  • 追问:预算按调用方还是被调用方? 通常按下游操作隔离,再视租户或优先级细分。
  • 追问:如何评价收益? 比较挽救成功数与额外负载、尾延迟和故障恢复时间。

八、加强记忆

重试预算要串起“可重试错误、幂等、deadline、退避、层级、总量”。先判断错误是否瞬态和操作能否安全重复,再确认剩余时间,用退避抖动发起有限额外尝试,并确保整条调用链只有合适的一层负责。最终用放大倍数衡量是否把故障越救越大。