HTTP 429 Too Many Requests 排查与治理:限流、重试与幂等设计

很多团队遇到 429 的第一反应是“流量太大”,然后粗暴调高限额。结果通常是两周后又爆一次,而且问题更难定位。429 的本质不是错误码,而是系统在告诉你:当前请求分布已经超过了你定义的容量边界。

1. 先搞清楚是哪个维度触发了 429

限流通常按多个维度叠加:用户、IP、Token、接口、租户、区域、设备。你需要先知道是哪一层在拦。最简单做法是在响应里补充可读字段,例如当前命中规则名、窗口大小、剩余令牌与重试时间。

如果响应只返回“Too Many Requests”,前端和调用方就只能盲重试,进一步放大压力。

2. 服务端要区分“保护系统”和“保护公平性”

同样是限流,目标不一样,策略也不同。

  • 保护系统稳定:优先在网关层做全局熔断,避免核心依赖被拖垮。
  • 保护租户公平:按租户或用户配额分桶,避免单个大客户抢占全部吞吐。

实操里建议“全局上限 + 租户配额 + 接口局部限速”三层组合,不要只压某一层。

3. 客户端重试必须遵守 Retry-After

如果你有 `Retry-After` 却没被客户端消费,这个头就等于没发。对 429 的正确处理顺序是:

  1. 优先读取 `Retry-After`(秒或时间戳)。
  2. 没有时使用指数退避 + 抖动,避免雪崩同步重试。
  3. 限制最大重试次数,避免后台任务无限堆积。

同一套 SDK 要覆盖 Web、移动端、服务端调用,避免不同端各自实现导致行为不一致。

4. 幂等设计是 429 场景的保险丝

429 往往发生在提交高峰,比如下单、支付、批量导入。如果调用方重试而接口不幂等,就会出现重复写入和数据污染。建议关键写接口统一支持幂等键(Idempotency-Key)并明确过期策略。

429 可以接受,重复扣款不可接受。优先保障写操作幂等,再谈重试成功率。

5. 监控要看“被拒请求”也看“被拯救请求”

只看 429 数量没有意义,要看结构:

  • 429 触发率按路由、租户、地区分布
  • 重试成功率与平均恢复时长
  • 触发 429 前后的 CPU、连接池、下游延迟
  • 重试队列深度与积压时间

这些指标一起看,才能区分是“阈值配置太保守”还是“系统容量真的到顶”。

上线检查清单

  • 429 响应包含可解析的限流信息与 `Retry-After`。
  • 客户端已统一接入退避重试策略,不会瞬时风暴重试。
  • 关键写接口支持幂等键,重试不会造成重复副作用。
  • 监控面板可以按租户/接口快速定位触发热点。

把 429 当成容量治理信号,而不是“临时报错”,你的 API 可用性会稳定很多。