curl -i https://api.example.com/api/report
# 期望 429 且带 Retry-After: 3
curl -s -D - -o /dev/null https://api.example.com/api/report | grep -i retry

限流触发后响应体是 {"code":429,"msg":"too many requests"},没有 Retry-After 头。调用方的 SDK 按固定的 100 毫秒连发 5 次,网关 QPS 从 800 涨到 4100,限流一直不解除。这类现象通常不是突然出现的,往前翻半天日志能看到苗头。

追下去是这么回事:限流组件只负责拒绝,没有把窗口剩余时间带出来。调用方拿不到建议等待时间,只能用默认的短间隔重试,请求量反而被放大。

「Retry-After 缺失」排查到最后往往是很小的一处差异,前面那些复杂猜测可以先放一放。权限不要一口气开到最大,先加到够用再往上试,范围小才好收。

把复现步骤压到三条以内,交给同事也能跑出来,才算真的定位清楚。改动写完就同步给同事,下一个人踩同一个坑,成本还是你的。

处理上按这个顺序:拒绝时返回 Retry-After 秒数和剩余额度;调用方按该头做退避 没有这个头就不重试;对同一来源的重试请求单独计数 避免重试打穿。

确认没问题再收工,触发限流后响应头里有 Retry-After: 3,调用间隔变成 3 秒,网关 QPS 回落到 900 以内。

作者 9823189