limit_conn是保护后端最底层有效的并发连接控制手段,基于TCP连接建立时计数,开销低,需先在http块定义limit_conn_zone,再在server或location中配置limit_conn绑定zone并设上限,支持单IP与全局双层防护,配合日志、状态码、限速及真实IP还原等参数提升实用性。

直接用 limit_conn 控制并发连接数,是保护后端资源最底层、最有效的手段之一。它不看请求内容、不解析 HTTP 头,只在 TCP 连接建立时计数,因此开销极低,特别适合防慢连接攻击、阻断连接耗尽类风险。
先定义共享内存区域(必须在 http 块)
这一步是前提,相当于“建一张计数表”,没有它,limit_conn 无法工作:
- 写法示例:
limit_conn_zone $binary_remote_addr zone=perip:10m; -
$binary_remote_addr比$remote_addr更省内存,每个 IP 约占 64 字节,10MB 可存约 16 万个独立客户端状态 - 若需按域名限流(如多租户场景),可用
$server_name;但避免用$uri或$args,键太多易撑爆内存 - 该指令只能放在
http{}块内,不能嵌套在server或location中
在 server 或 location 中启用限制
真正起作用的配置在这里,绑定前面定义的 zone 并设定上限:
- 例如:
limit_conn perip 15;表示每个客户端 IP 最多维持 15 个并发连接 - 可叠加使用:
limit_conn perip 15; limit_conn conn_total 1000;(需提前定义conn_totalzone),实现“单 IP + 全局”双层防护 - 注意:HTTP/2 的一个连接算作 1 个连接,不管里面有多少 stream;keepalive 空闲连接也持续占配额,建议配合
keepalive_timeout 15;缩短生命周期
搭配关键参数提升实用性
单独限连接数够用,但加几行就能更可控、更可观测:
-
limit_conn_log_level error;:把触发限流的日志级别从默认warn提到error,避免刷屏 -
limit_conn_status 503;:明确返回 503(也可设为 429,语义更准) -
limit_rate 256k;:对已被限流但仍存活的连接降速,防止大文件下载长期卡住连接 - 在
log_format中加入$limit和$limit_key,方便在 access log 里看到谁被限、因何被限
验证与避坑要点
上线前务必实测,否则容易误伤正常用户:
- 用
hey -n 100 -c 30 http://yoursite.com/模拟高并发,观察是否部分请求返回 503 - 查错误日志:
tail -f /var/log/nginx/error.log,出现limiting connections by zone即表示生效 - 若前端是 Vue/React SPA,注意
try_files $uri $uri/ /index.html会把所有路由都走同一 server 块,所有请求(含图片、JS、API)都计入连接数——频繁刷新或多个标签页易触发限制 - 经过 CDN 或 SLB 时,
$binary_remote_addr默认取的是代理 IP,需加set_real_ip_from和real_ip_header X-Forwarded-For才能还原真实客户端 IP











