nginx限制单个ip并发连接数需三步:一是在http块用$binary_remote_addr定义limit_conn_zone共享内存区(如zone=perip:10m);二在server或location中配置limit_conn perip n启用限制;三在代理环境下改用$realip_remote_addr并配置realip_module还原真实ip。

在 nginx.conf 中限制单个 IP 的最大并发连接数,核心是使用 limit_conn_module 模块,分三步完成:定义共享内存区、指定限流键、在请求入口处启用限制。它统计的是当前已建立且未关闭的 TCP 连接(包括 keepalive、HTTP/2 stream、WebSocket),不是请求数,适合防爬虫、防连接耗尽。
1. 在 http 块顶部定义 limit_conn_zone
必须放在 http{} 最外层,不能嵌套在 server 或 upstream 里,否则启动报错 unknown limit_conn_zone:
- 推荐用
$binary_remote_addr作 key:IPv4 固定 4 字节,IPv6 固定 16 字节,比$remote_addr更省内存、抗哈希冲突 -
zone=perip:10m表示创建名为perip的共享内存区,大小 10MB,约支持 16 万~32 万个独立 IP 的连接状态 - 若日志出现
limit_conn: cannot add connection,说明内存不足,可调大为20m
配置示例:
limit_conn_zone $binary_remote_addr zone=perip:10m;2. 在 server 或 location 块中启用 limit_conn
规则加在接收客户端请求的位置,生效范围取决于放置位置:
- 加在
server块开头(紧贴server_name后):整站生效 - 加在
location /api/内:仅对该路径生效,不影响静态资源或首页 -
limit_conn perip 5表示每个 IP 最多维持 5 个并发连接;数值建议设 3~10:太小(如 1)易误伤多标签页用户,太大(如 50)起不到防护作用
配置示例(全站限制):
server {listen 80;
server_name example.com;
limit_conn perip 5;
location / {
proxy_pass http://backend;
}
}
3. 代理环境必须还原真实 IP
如果 Nginx 前有 CDN、WAF、SLB 或云负载均衡,$binary_remote_addr 拿到的是代理节点 IP,会导致所有用户被当成同一个 IP 限流或完全失效:
- 确认已编译启用
http_realip_module(常见发行版默认包含) - 用
set_real_ip_from明确声明可信上游网段(如 Cloudflare 官方 IP 段、阿里云 SLB 网段) - 设置
real_ip_header X-Forwarded-For(或X-Real-IP,依上游实际传递的头而定) - 把限流 key 改为
$realip_remote_addr,例如:limit_conn_zone $realip_remote_addr zone=perip:10m;
4. 建议补充的增强配置
让限流更可控、更易排查、更符合生产规范:
-
limit_conn_status 429;:超限时返回标准 HTTP 状态码429 Too Many Requests,便于前端识别和自动重试 -
limit_conn_log_level error;:只在真正超限时记录 error 级日志,避免 info 级刷屏 - 搭配
limit_req zone=perip burst=10 nodelay;防短连接高频刷接口(需先定义limit_req_zone) - 搭配
limit_rate 200k;控制单连接带宽,防止单连接吃满出口











