limit_conn限制单ip并发连接需三步:一、http块定义共享内存区,用$binary_remote_addr作key;二、server或location中启用limit_conn perip n;三、代理环境需用realip模块还原真实ip并改用$realip_remote_addr。

直接用 limit_conn 限制单 IP 并发连接,核心就三步:定义共享内存区、启用连接计数、适配真实 IP 场景。它限制的是「已建立且未关闭」的 TCP 连接数,不是请求数,对下载、登录、长轮询等高能耗路径特别有效。
一、在 http 块中定义连接计数区域
这一步是基础,必须写在 http{} 最外层,否则启动会报错 unknown limit_conn_zone:
- 推荐用
$binary_remote_addr作 key:固定长度(IPv4 为 4 字节),省内存、防伪造、不依赖请求头 -
zone=perip:10m表示创建名为perip的共享内存区,大小 10MB,约支持 16 万独立 IP - 若后端用户量大(如百万级真实访客),建议设为
20m或更高,避免出现limit_conn: cannot add connection
配置示例:
limit_conn_zone $binary_remote_addr zone=perip:10m;二、在 server 或 location 中启用限制
规则加在接收请求的位置——全站控制放 server 块开头,精准防护只放具体 location(如仅限 /api/ 或 /download/):
-
limit_conn perip 5;表示每个唯一 IP 最多维持 5 个活跃连接 - HTTP/1.1 keepalive、WebSocket、HTTP/2 多路复用都算作一个连接;浏览器默认并行 6 连接,设 3~5 是较稳妥的起点
- 若
server和location都配置了limit_conn,以数值更小的那个为准
示例(仅保护下载接口):
location /download/ {limit_conn perip 3;
proxy_pass http://backend;
}
三、代理环境下必须还原真实 IP
如果 Nginx 前有 CDN、WAF 或 SLB,$binary_remote_addr 拿到的是代理节点 IP,所有用户会被当成同一个 IP 限流或完全失效:
- 确认已启用
http_realip_module(多数编译版默认包含) - 用
set_real_ip_from声明可信上游网段(如 Cloudflare 的 IP 段或你自己的 LB 内网段) - 设置
real_ip_header X-Forwarded-For;(或X-Real-IP,依上游实际传的头而定) - 把 zone 的 key 改为
$realip_remote_addr:
limit_conn_zone $realip_remote_addr zone=perip:10m;
四、增强可用性与可观测性
让限流更可控、问题更易定位:
-
limit_conn_status 429;返回标准状态码,比默认 503 更利于前端识别和自动重试 -
limit_conn_log_level error;只在真正超限时记 error 日志,避免日志刷屏 - 搭配
limit_req控制请求速率(防短连接刷接口),两者正交不冲突 - 必要时加
limit_rate 200k;防止单连接吃满带宽,尤其用于大文件场景











