Nginx Stream连接限流需在全局启用limit_conn_zone定义IP级共享内存区,再于server块中用limit_conn限制并发数,超限时发RST拒绝连接;须配合proxy_timeout、系统文件描述符调优及stream日志验证。

直接在 Nginx 的 stream 上下文中配置连接限流,就能有效防止单个 IP 对 TCP 代理端口(如数据库、Redis、SSH 转发等)发起过多并发连接,避免耗尽文件描述符或打垮后端服务。关键不是限制请求频率,而是掐在连接建立阶段——超限即断,不转发、不排队、零后端开销。
启用 stream 模块并定义 IP 级限流区域
stream 模块默认不启用,需确认 Nginx 编译时含 --with-stream。限流必须在 stream{} 块外、全局层级定义共享内存区:
- 在
nginx.conf顶部(http块之外)添加:limit_conn_zone $binary_remote_addr zone=conn_per_ip:10m; -
$binary_remote_addr是二进制格式的客户端 IP,比字符串省空间;10m内存约支持 16 万独立 IP 的连接计数 - 若日志出现
limit_conn: cannot add connection,说明内存不足,可调大至20m
在 TCP server 块中应用并发限制
限流指令必须写在 stream 块内的具体 server 中,不能放在 http 或 location 里:
- 示例:限制每个 IP 最多 5 个并发 TCP 连接
stream {<br> server {<br> listen 6379;<br> proxy_pass redis_backend;<br> limit_conn conn_per_ip 5;<br> }<br>} - 可叠加全局限制,例如本机所有监听端口总连接不超过 1000:
先定义limit_conn_zone $server_addr zone=addr:10m;,再在server中加limit_conn addr 1000; - 触发限流时,Nginx 直接发送 TCP RST 包拒绝新连接,返回状态不可见(无 HTTP 状态码),但连接建立失败
识别真实客户端 IP(有前置代理时)
如果 TCP 流量经过 SLB、云防火墙或四层网关,$binary_remote_addr 会是代理 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) - 调整 Nginx worker 连接能力:
events { worker_connections 4096; },避免单 worker 过载 - 开启 stream 日志验证效果:
access_log /var/log/nginx/stream.log main;,日志中状态字段为503表示限流拒绝


















