Nginx限速按连接限速与按IP限速区别
先分清两个模块管什么
Nginx 的限速主要靠 ngx_http_limit_conn_module 和 ngx_http_limit_req_module 两个模块。按连接限速限制的是“同时保持的连接数”,一个客户端同时开着几个下载或长连接就占几个;按 IP 限速通常指按请求频率限速,限制的是“单位时间内发起的请求次数”。
简单说,连接限速防的是并发占用,请求限速防的是高频刷接口。
判断你该用哪个,可以看现象:如果服务器带宽被少数几个大文件下载占满,优先考虑 limit_conn;
如果某个 IP 每秒请求上百次导致 CPU 飙升,优先考虑 limit_req。
两者可以同时开启,互不冲突。
前置准备与配置位置
操作前确认 Nginx 已安装并能正常重载配置:
nginx -v
nginx -t
限速配置通常写在 nginx.conf 的 http 块中定义共享内存区域,再在 server 或 location 块中引用。
编辑前先备份:
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
宝塔面板用户可在“软件商店 → Nginx → 配置修改”中编辑,路径一般也是 /www/server/nginx/conf/nginx.conf。
按连接数限速的写法
在 http 块中定义连接计数区域:
limit_conn_zone $binary_remote_addr zone=perip_conn:10m;
limit_conn_zone $server_name zone=perserver_conn:10m;
$binary_remote_addr 是客户端 IP 的二进制形式,
比 $remote_addr 更省内存。10m 是共享内存大小,
能记录的 IP 数量有限,
IP 很多时要适当调大。
在 server 或 location 中引用:
server {
listen 80;
server_name example.com;
limit_conn perip_conn 5;
limit_conn perserver_conn 100;
location /download/ {
limit_conn perip_conn 2;
limit_rate 512k;
}
}
上面表示每个 IP 最多同时 5 个连接,整个虚拟主机最多 100 个连接,下载目录每个 IP 最多 2 个。limit_conn 统计的是当前活跃连接数,连接释放后计数会下降。
按请求频率限速的写法
同样在 http 块定义限流区域:
limit_req_zone $binary_remote_addr zone=perip_req:10m rate=10r/s;
rate=10r/s 表示每个 IP 平均每秒 10 个请求。
在 location 中引用:
location /api/ {
limit_req zone=perip_req burst=20 nodelay;
limit_req_status 429;
}
burst=20 允许突发 20 个请求排队,nodelay 表示突发请求立即处理而不是延迟处理。limit_req 统计的是请求速率,即使连接很快关闭,请求次数依然会被计数。
常见报错与避坑提醒
配置后执行 nginx -t,
如果提示 unknown directive "limit_conn_zone",
说明当前 Nginx 编译时未包含该模块,
可用 nginx -V 查看编译参数确认。
几个容易踩的坑:
limit_conn_zone和limit_req_zone必须写在http块,不能写在server里,否则启动报错。- 共享内存区域名字不能重复定义,多个
zone要起不同名字。 - 使用 CDN 或反向代理时,
$binary_remote_addr拿到的是上一跳 IP,需要配合real_ip模块还原真实客户端 IP。 limit_req的rate不支持小数写法如0.5r/s,需要换算成整数或改用r/m。- 限速阈值设得过低会误伤正常用户,建议先观察访问日志再定值。
效果验证方法
重载配置:
nginx -s reload
用 ab 或 curl 并发测试连接限制:
ab -n 100 -c 20 http://example.com/download/test.zip
观察是否出现 503(连接超限默认返回码)或 429(请求限速返回码)。
同时查看错误日志确认触发记录:
tail -f /var/log/nginx/error.log
日志中会出现 limiting connections 或 limiting requests 关键字,说明限速规则已生效。
如果完全没有相关记录,先检查配置是否写在正确的块中,以及 nginx -t 是否通过。
几个实际会问到的问题
按 IP 限速就是 limit_req 吗? 严格说 limit_req 是按 key 限速,key 可以是 IP,也可以是 $server_name 或其他变量。
日常说的“按 IP 限速”多数指用 $binary_remote_addr 做 key 的请求频率限制。
两个模块能同时用吗? 可以。
连接限速和请求限速作用于不同维度,同时配置不会冲突,适合既防并发又防刷接口的场景。
为什么限速没生效? 常见原因是配置写在了错误的块、重载失败、或者请求经过了 CDN 导致 IP 判断错误。
按 nginx -t 输出和错误日志逐项排查即可。