Nginx TCP连接数限制需通过stream模块的limit_conn实现,配置limit_conn_zone于全局,server块中应用limit_conn指令,并配合realip、超时及系统调优。

在 Nginx 中对 TCP 代理做连接数限制,核心是用 stream 模块 的 limit_conn 功能,在连接建立阶段直接拒绝超限请求,不转发、不排队,开销极低。它不是限请求频率,而是控并发连接数,适用于数据库、Redis、SSH 等四层代理场景。
启用 stream 模块并定义 IP 级限流区域
Nginx 默认不启用 stream 模块,需确认编译时含 --with-stream(主流发行版通常已内置)。限流配置必须写在全局层级(http 块之外),不能放在 http 或 location 里:
- 在
nginx.conf顶部添加:limit_conn_zone $binary_remote_addr zone=conn_per_ip:10m; -
$binary_remote_addr是二进制格式客户端 IP,比字符串更省内存;10MB 内存约支持 16 万个独立 IP 计数 - 若日志出现
limit_conn: cannot add connection,说明内存不足,可调大至20m
在 TCP server 块中应用并发限制
限流指令必须写在 stream{...} 内的具体 server 块中:
- 示例(限制单个 IP 最多 5 个 Redis 连接):
stream {<br> server {<br> listen 6379;<br> proxy_pass redis_backend;<br> limit_conn conn_per_ip 5;<br> }<br>} - 可叠加全局限制:先定义
limit_conn_zone $server_addr zone=addr:10m;,再在server中加limit_conn addr 1000;,控制本机所有监听端口总连接数 - 触发限流时,Nginx 直接发 TCP RST 包断连,无 HTTP 状态码,客户端表现为“连接被拒绝”
处理真实客户端 IP(有前置代理时)
若流量经过 SLB、云防火墙或四层网关,$binary_remote_addr 会是代理 IP,需提取真实源 IP:
- 启用
ngx_stream_realip_module(主流 Nginx 包已编译) - 在
stream块开头配置:set_real_ip_from 10.0.0.0/8;<br>set_real_ip_from 172.16.0.0/12;<br>real_ip_header proxy_protocol;
- 要求上游代理开启 PROXY 协议(如 AWS NLB、HAProxy),Nginx 才能从协议头解析真实 IP
- 之后改用
$remote_addr(经 realip 处理后已是真实 IP)作为 key 定义 zone
配合超时与系统资源调优
限流只是第一道防线,还需防止连接空转和系统瓶颈:
- 设置合理代理超时:
proxy_timeout 30s;(默认 60s),及时释放无数据连接 - 检查系统级限制:
fs.file-max(建议 ≥ 200000)、用户级ulimit -n(建议 ≥ 65536) - 在
events块中设worker_connections 4096;,避免单个 worker 过载 - 开启 stream 日志便于验证:
access_log /var/log/nginx/stream.log main;,日志中状态码为503表示限流生效


















