跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

如何在Nginx中利用Limit-Conn-Zone配置单IP在全站范围内的并发限制

limit_conn_zone是Nginx中定义并发连接限制共享内存区的指令,必须置于http块内,以$binary_remote_addr为键可精准按真实IP限流,配合limit_conn方可实现全站单IP并发控制。 什么是
limit_conn_zone
,它真能限制单IP全站并发吗 能,但有个关键前提:它只对连接数生效,不是请求数。用户开10个标签页、用HTTP/2复用连接,可能只占1个连接;而短连接频繁请求却会快速耗尽配额。Nginx不解析HTTP层的“用户身份”,
$binary_remote_addr
是唯一可靠且内存友好的IP标识方式——它自动压缩IPv4为4字节、IPv6为16字节,比用
$remote_addr
节省约60%共享内存空间。 常见误用是写成
limit_conn_zone $remote_addr zone=perip:10m
,这会导致IPv6地址被截断,后续匹配失败,看似限流无效。 必须用
$binary_remote_addr
作为key zone大小不能太小:10MB约支持8万IP(按平均32字节/key估算),高流量站点建议从20m起步 该指令只能出现在
http
块,不能放在
server
或
location
内
limit_conn
放在哪个位置才真正作用于“全站” 放在
http
块最外层,才能覆盖所有
server
和
location
。若只放在某个
server
块里,就只对该域名生效;若放在
location /api/
,那静态资源和首页完全不受控。 注意:一个连接对应一个TCP连接,无论这个连接上发了多少个HTTP请求(尤其在keepalive开启时)。所以实际并发感知比想象中“宽松”。 正确写法:
http { limit_conn_zone $binary_remote_addr zone=perip:20m; limit_conn perip 10; ... }
错误写法:
limit_conn perip 10
单独写在
location
里——它不会继承
http
块的定义,会报错“unknown limit_conn zone” 若需差异化策略(如API更严、静态资源放宽),得用多个
limit_conn_zone
+ 多个
limit_conn
组合,不能靠条件判断 为什么加了配置却没看到503,或者日志里全是“limiting connections”却没生效 典型原因是没有启用
limit_conn_log_level
和
limit_conn_status
,导致行为不可见。默认情况下,超限时Nginx只记一条error日志,不返回503,客户端甚至感知不到被限——它只是被挂起,直到有连接释放。 Nginx 在宝塔面板中轻松管理Nginx高性能Web服务器。提供可视化配置反向代理、负载均衡、SSL证书及HTTP缓存功能,一键优化高并发性能,助您高效搭建稳定、快速的网站运行环境。 下载 更隐蔽的问题是:如果后端是长连接代理(如gRPC或WebSocket),
limit_conn
会把整个连接计为1,但业务逻辑可能允许它持续占用几十秒甚至几分钟,造成“假性拥堵”。 务必显式设置:
limit_conn_log_level warn;
和
limit_conn_status 503;
检查access日志是否包含
$limit
变量(需编译时含
--with-http_realip_module
才能准确识别真实IP) 用
ss -tn | grep :80 | wc -l
配合
ab -n 100 -c 50 http://your.site/
实测,比看日志更快验证 与
limit_req
混用时要注意什么
limit_conn
和
limit_req
解决的是不同维度问题:前者管“同时有几个TCP连接”,后者管“每秒最多几个请求”。两者可共存,但顺序和作用域必须理清。 例如:你设了
limit_conn perip 5
和
limit_req zone=burst burst=20 nodelay
,那么一个IP最多维持5个连接,每个连接内每秒最多处理4个请求(20÷5)。但如果用户用curl反复新建连接,
limit_conn
会先拦住第6个连接,
limit_req
根本没机会触发。 不要在同一个
location
里对同一zone既做
limit_conn
又做
limit_req
,容易互相干扰 如果用了
proxy_pass
,确保
limit_conn
在
proxy_pass
之前执行——它基于Nginx接收连接的时刻判断,不是后端响应时刻 HTTP/2下,单连接多路复用会使
limit_conn
显得“过于宽泛”,此时应优先考虑
limit_req
+
burst
控制QPS 真正难的是平衡:设太松挡不住爬虫,设太紧误伤移动端弱网用户。上线前一定要用真实网络环境(比如4G模拟)跑一轮压测,而不是只看本地
ab
结果。

相关文章