一、Nginx 限流能做什么?
Nginx 原生支持 请求限速 / 并发限速,常用于:
- 防刷接口
- 防爬虫
- 防止 PHP-FPM 被打满
- API QPS 控制
- 登录 / 下单接口保护
二、Nginx 限流的两大核心模块
| 模块 | 作用 |
|---|---|
limit_req | 请求频率限制(QPS) |
limit_conn | 并发连接数限制 |
👉 生产环境 两个一般一起用
三、最常用:按 IP 限制请求频率(QPS)
1️⃣ 定义限流区(http 块)
http {
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
}参数解释
$binary_remote_addr:客户端 IP(推荐)zone=api_limit:10m:共享内存区(约 16 万 IP)rate=10r/s:每秒 10 个请求
2️⃣ 在 location 启用限流
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://backend;
}参数说明
| 参数 | 含义 |
|---|---|
burst=20 | 突发允许 20 个请求 |
nodelay | 突发请求不延迟,直接放行 |
3️⃣ 不加 nodelay 的效果(平滑限流)
limit_req zone=api_limit burst=20;👉 超出的请求会 排队延迟
四、按并发连接数限流(防拖死后端)
1️⃣ 定义连接区
http {
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
}2️⃣ 启用连接限制
location /api/ {
limit_conn conn_limit 5;
}👉 每个 IP 同时最多 5 个连接
五、组合使用(生产强烈推荐)
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
limit_conn conn_limit 5;
proxy_pass http://backend;
}六、返回自定义错误码(非常重要)
默认返回 503,建议改成 429
limit_req_status 429;
limit_conn_status 429;七、白名单 / 黑名单(绕过限流)
1️⃣ 白名单 IP 不限流
geo $limit {
default 1;
127.0.0.1 0;
10.0.0.0/8 0;
}
map $limit $limit_key {
0 "";
1 $binary_remote_addr;
}
limit_req_zone $limit_key zone=api_limit:10m rate=10r/s;2️⃣ 针对 User-Agent / API Key 限流
limit_req_zone $http_x_api_key zone=key_limit:10m rate=5r/s;八、只限制某些接口(常见)
location = /api/login {
limit_req zone=api_limit burst=5 nodelay;
}
location = /api/order {
limit_req zone=api_limit burst=3 nodelay;
}九、如何验证限流是否生效?
使用 ab / wrk
ab -n 1000 -c 50 http://localhost/api/test返回:
HTTP/1.1 429 Too Many Requests说明生效。
十、常见坑(你一定会踩)
❌ 用 $remote_addr
- IPv6 / 代理下不准
- 推荐
$binary_remote_addr
❌ zone 太小
- IP 多时会频繁淘汰
- 建议 10m 起步
❌ 没加 burst
- 正常请求也被误伤
❌ 所有接口一刀切
- 登录 / 下单 / 查询应该不同策略
十一、生产参数建议(参考)
| 场景 | rate | burst |
|---|---|---|
| 普通 API | 10r/s | 20 |
| 登录接口 | 2r/s | 5 |
| 下单接口 | 1r/s | 3 |
| 内部服务 | 不限 | - |
十二、一句话总结(可以直接记)
**Nginx 限流靠limit_req控频率,limit_conn控并发;
burst 防误伤,429 更规范,生产环境两者一起用。**