HTTP 429 Too Many Requests 排查与治理:限流、重试与幂等设计
很多团队遇到 429 的第一反应是“流量太大”,然后粗暴调高限额。结果通常是两周后又爆一次,而且问题更难定位。429 的本质不是错误码,而是系统在告诉你:当前请求分布已经超过了你定义的容量边界。
1. 先搞清楚是哪个维度触发了 429
限流通常按多个维度叠加:用户、IP、Token、接口、租户、区域、设备。你需要先知道是哪一层在拦。最简单做法是在响应里补充可读字段,例如当前命中规则名、窗口大小、剩余令牌与重试时间。
如果响应只返回“Too Many Requests”,前端和调用方就只能盲重试,进一步放大压力。
2. 服务端要区分“保护系统”和“保护公平性”
同样是限流,目标不一样,策略也不同。
- 保护系统稳定:优先在网关层做全局熔断,避免核心依赖被拖垮。
- 保护租户公平:按租户或用户配额分桶,避免单个大客户抢占全部吞吐。
实操里建议“全局上限 + 租户配额 + 接口局部限速”三层组合,不要只压某一层。
3. 客户端重试必须遵守 Retry-After
如果你有 `Retry-After` 却没被客户端消费,这个头就等于没发。对 429 的正确处理顺序是:
- 优先读取 `Retry-After`(秒或时间戳)。
- 没有时使用指数退避 + 抖动,避免雪崩同步重试。
- 限制最大重试次数,避免后台任务无限堆积。
同一套 SDK 要覆盖 Web、移动端、服务端调用,避免不同端各自实现导致行为不一致。
4. 幂等设计是 429 场景的保险丝
429 往往发生在提交高峰,比如下单、支付、批量导入。如果调用方重试而接口不幂等,就会出现重复写入和数据污染。建议关键写接口统一支持幂等键(Idempotency-Key)并明确过期策略。
429 可以接受,重复扣款不可接受。优先保障写操作幂等,再谈重试成功率。
5. 监控要看“被拒请求”也看“被拯救请求”
只看 429 数量没有意义,要看结构:
- 429 触发率按路由、租户、地区分布
- 重试成功率与平均恢复时长
- 触发 429 前后的 CPU、连接池、下游延迟
- 重试队列深度与积压时间
这些指标一起看,才能区分是“阈值配置太保守”还是“系统容量真的到顶”。
上线检查清单
- 429 响应包含可解析的限流信息与 `Retry-After`。
- 客户端已统一接入退避重试策略,不会瞬时风暴重试。
- 关键写接口支持幂等键,重试不会造成重复副作用。
- 监控面板可以按租户/接口快速定位触发热点。
把 429 当成容量治理信号,而不是“临时报错”,你的 API 可用性会稳定很多。