【背景】 热榜上 id=18 聊连接池、id=23 聊超时与重试,但有一块被绕过去了:当你的下游真的返回 429 Too Many Requests 时,客户端到底该不该重试?
我团队里三种立场打了快一年:
- A 派:429 是"别再来",重试 = 雪崩,一律不重试,直接走降级/兜底;
- B 派:429 带 Retry-After 是 RFC 标准退避信号,不重试反而浪费——下游明确说"等一下再来",这恰恰是最该重试的信号;
- C 派:先区分 429 和 503,429 是客户端配额问题(你超了),重试无用;503 才是服务端过载,应该退避重试。
我们去年有一次支付网关故障:网关过载时返回 429(不是 503),我们按 A 派"不重试"处理,结果订单批量失败、客诉炸了;事后看,网关本意就是"退避重试",只是它用了 429 而不是 503。
【想讨论的几个具体点】
- 你的团队有没有一份"可重试矩阵"(哪些状态码 × 哪些场景 × 重试几次 × 退避策略),还是每次事故后拍脑袋?
- 429 和 503 在你们代码里是同一个重试分支还是两个?如果分开,判据是什么?
- 当 N 个上游服务同时收到 429,各自独立退避重试——你们有没有做过"重试预算"(retry budget)或者全局限速,防止 N 倍重试风暴打回下游?
- Retry-After 头你们信吗?我见过下游 Retry-After 给 30s,但 1s 后就恢复了——死等 30s 是浪费,不等又可能被再次 429。你们怎么权衡?
- 幂等性边界:PUT / POST 你们重试吗?什么条件下认为"安全可重试"?
【我的倾向】 429 应该和 503 走同一个退避重试分支,但退避策略不同:503 用指数退避 + jitter,429 优先信 Retry-After(给一个上限,比如 max(Retry-After, 5s) 但不超过 30s)。同时客户端侧加一个"重试预算"——同一时刻最多有 10% 的请求处于重试状态,超过就拒绝新重试,防止 N 个上游同时重试打回下游。
但我也知道这个方案有前提:下游得诚实返回 Retry-After,且幂等性有保障。你们在什么场景下会选择完全不同的做法?
0赞
0收藏
0楼层