Nginx限流需两步:一是在http块中用limit_req_zone定义共享内存区(如zone=api_limit:10m rate=10r/s),二是在location中用limit_req启用规则(如burst=5 nodelay);注意不可错放指令位置,需用并发工具测试并配合nginx -t验证。

直接在 Nginx 配置中启用 limit_req 模块,就能对指定接口做请求频率控制。它不依赖后端,性能高、生效快,关键是两步:先定义限流区域,再在具体路径上启用规则。
一、在 http 块里定义限流区域
这是所有限流的基础,必须放在 http{...} 大括号内,不能写在 server 或 location 里。
-
$binary_remote_addr是推荐的键,用二进制格式存 IP,比$remote_addr更省内存 -
zone=api_limit:10m表示建一个叫api_limit的共享内存区,大小 10MB(约支持 15–30 万个独立 IP) -
rate=10r/s表示每秒最多放行 10 个请求;也支持60r/m(每分钟 60 次),适合短信、注册类接口
示例配置:
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
}
二、在 location 块中启用限流规则
把限流真正作用到某个接口路径,比如 /api/login 或 /v1/data。
-
limit_req zone=api_limit是最简写法,超出速率的请求会排队等待(按令牌桶节奏慢慢放行) -
burst=20表示允许最多 20 个请求进入缓冲队列;第 21 个才被拒绝 -
nodelay表示“有队列位置就立刻处理”,不等令牌匀速释放;加了它,burst 内的请求不会卡顿,但瞬时压力会上去 - 想让超限请求返回 503,可加
limit_req_status 503;;默认是 503,不写也行
示例配置:
location /api/login {limit_req zone=api_limit burst=5 nodelay;
proxy_pass http://backend;
}
三、注意几个易错点
配完常遇到“没效果”或“全卡住”,多半是这几个细节没调好:
- 只配
limit_req_zone不配limit_req,等于定义了规则但从不执行 - 误把
limit_req写在http块里——它只能出现在server或location中 -
burst不是“允许超速”,而是“最多缓存几个等令牌”,不加nodelay时,这 20 个请求仍要排队,用户会明显感觉延迟甚至超时 - 测试时别用单条
curl,得用ab -c20 -n100或wrk -t4 -c50 -d5s模拟并发,否则看不出 burst 和排队效果
四、验证和调优建议
改完配置别急着 reload,先检查语法:
nginx -t再重载:
nginx -s reload验证是否生效,可以看 access log 或用 curl -I 观察响应头是否有 X-RateLimit-Limit 类字段(需配合第三方模块或自定义日志格式);更直接的是开 stub_status 查看实时连接与请求统计。
如果发现大量 503,先确认是不是 burst 设太小,或者 rate 定得太严;若接口本身响应慢(如查库耗时 800ms),建议适当调高 burst 值,避免正常用户也被拦住。











