Nginx原生limit_req模块基于漏桶算法,不支持严格滑动窗口,但通过rate=5r/m、burst=5、nodelay组合可逼近“最近60秒最多10次”的滑动窗口效果,适用于注册接口防刷。

1. 定义按 IP 动态计数的限流区域
使用 `$binary_remote_addr` 作为键,确保同一 IP 的请求被统一计数;内存大小设为 `10m` 可支撑约 16 万个 IP 状态:
http {
limit_req_zone $binary_remote_addr zone=reg_limit:10m rate=5r/m;
}
这里设为 5r/m(每分钟 5 次),比秒级(如 1r/s)更贴近滑动窗口的时间粒度,避免秒级突刺误判。注意:`rate` 支持 `r/m` 单位,Nginx 内部会换算为等效的毫秒级漏桶速率。
2. 在注册路径启用带缓冲的突发处理
在 `location /api/register` 中应用限流,并启用突发缓冲与无延迟模式,让合法的短时重试(如用户点快了两次)能快速通过,而非排队等待:
location /api/register {
limit_req zone=reg_limit burst=5 nodelay;
proxy_pass http://auth_backend;
}
解释:
• `burst=5`:允许最多 5 个请求暂存于缓冲区
• `nodelay`:缓冲区内请求立即处理,不匀速释放
• 实际效果 ≈ “最近 60 秒内最多 10 次请求”(5 基础 + 5 缓冲),因漏桶速率缓慢清空缓冲,旧请求自然过期,形成近似滑动窗口的衰减感
3. 可选:排除可信来源(如管理后台、内部调用)
避免限制运维或内部系统调用,用 `geo` + `map` 动态控制限流 key:
geo $trusted {
default 0;
192.168.10.0/24 1;
127.0.0.1 1;
}
map $trusted $reg_key {
1 ""; (白名单 → 空key → 不限流)
0 $binary_remote_addr;
}
limit_req_zone $reg_key zone=reg_limit:10m rate=5r/m;
4. 补充防护建议
注册接口还需叠加其他维度防护,避免单靠 IP 限流被绕过:
- 加 `limit_conn` 限制单 IP 并发连接数(防多线程暴力注册):`limit_conn conn_reg 3;`
- 校验前端传来的验证码或 Token,服务端验证通过后再进入限流逻辑(推荐在 proxy_pass 前用 Lua 或后端做)
- 记录被限流的请求到日志(添加 `limit_req_log_level warn;`),便于分析攻击特征
- 对返回 503 的请求,可自定义错误页或 Header(如 `add_header X-RateLimit-Remaining "0";`)











