nginx 限单ip并发连接需在http块定义limit_conn_zone并用$binary_remote_addr或$realip_remote_addr作key,再于server或location中配置limit_conn;须配合realip模块还原真实ip,并可组合limit_req、limit_rate增强防护。

在 Nginx 负载均衡场景下限制单个 IP 的并发连接数,核心不是改 upstream,而是把限流逻辑放在 proxy 服务端(即 Nginx 本身)的 http 或 server 块中。负载均衡只负责转发,真正的连接计数和拦截必须由 Nginx 的 limit_conn 模块完成,且必须配合 limit_conn_zone 才生效。
必须在 http 块定义共享内存区
这是整个机制的基础,不能省略,也不能写错位置:
- 只能放在
http{}最外层,不能嵌套在server或upstream里,否则启动报错:unknown limit_conn_zone - 推荐用
$binary_remote_addr作 key,固定长度、省内存、安全可靠 - 内存大小按实际需求设:10m ≈ 支持 16 万独立 IP;若后端有几十万真实用户,建议设为 20m 或更高
示例配置:
在 server 或 location 中启用限制
限流规则要加在接收客户端请求的地方,也就是 server 块(全站生效)或具体 location(如仅限 API):
- 若想对所有经由负载均衡的流量统一限流,就把
limit_conn perip 5;放在server块开头(紧贴listen和server_name后) - 若只保护后端某个服务(如 /api),则写在对应
location /api/ { ... }内 - 注意:它限制的是「已建立未关闭」的 TCP 连接数,不是请求数;HTTP/1.1 keepalive、WebSocket、HTTP/2 stream 都计入
代理环境下必须还原真实 IP
负载均衡前通常有 CDN、SLB 或 WAF,此时 $binary_remote_addr 拿到的是代理节点 IP,不是用户真实 IP:
- 确认 Nginx 已编译启用
http_realip_module - 用
set_real_ip_from明确声明可信上游网段(如 Cloudflare 的 IP 段) - 设置
real_ip_header X-Forwarded-For;或X-Real-IP(依上游实际传的头而定) - 把限流 key 改为
$realip_remote_addr,例如:
limit_conn_zone $realip_remote_addr zone=perip:10m;
增强防护与可观测性
单纯限连接数在高并发或 HTTP/2 场景下可能不够,建议组合使用:
- 加
limit_conn_log_level error;,只在真超限时记日志,避免刷屏 - 设
limit_conn_status 429;,返回标准状态码便于前端识别和重试 - 搭配
limit_req控制请求速率(防短连接刷接口),例如:
limit_req zone=perip_rate burst=10 nodelay; - 必要时加
limit_rate 200k;防止单连接吃满带宽











