limit_req_zone $binary_remote_addr zone=anon:10m rate=20r/s;
# 已登录请求改按 uid 计数
limit_req_zone $http_x_uid zone=user:10m rate=5r/s;

上午十点一批用户反馈登录提示请求过于频繁,限流日志里同一个 IP 一小时内出现两万次请求,往下翻全是正常登录和刷新首页。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。

原因不复杂,限流键取了 X-Forwarded-For 的第一段,办公网经过 NAT 之后几百人共用一个出口 IP,按 IP 计数等于把整栋楼当成一个用户在刷接口,正常请求只能一起被拦。

「限流 IP 误伤」改完先别急着全量,挑一台机器放半天,真有问题这段时间就能看出来。备份不是备了就行,恢复一次才算数,很多备份文件打开才发现是空的。

处理上按这个顺序:匿名接口按 IP 来限流,登录之后的接口改成按用户 id 计数;IP 的阈值要按出口规模放大,别照着单个用户的使用量去估;触发限流的时候统一返回 429,并带上 Retry-After 响应头让客户端知道多久再来。

改完只确认一件事:同一出口下多个账号都能正常登录,单账号高频刷接口仍被 429。

作者 9823189