Nginx stream模块TCP转发需协同调优worker_connections、文件描述符、内核队列及事件模型:必须设置worker_rlimit_nofile与ulimit -n匹配,调高net.core.somaxconn和tcp_max_syn_backlog,events块中启用epoll、multi_accept,并在stream中合理配置proxy_timeout等参数。

用 Nginx 的 stream 模块做 TCP 转发时,worker_connections 不是孤立调大的数字,它必须和内核队列、文件描述符、事件模型三者咬合才能真正撑住高并发连接。单纯改一个值,很容易在压测中突然出现连接拒绝、超时或 too many open files 报错。
先对齐系统级资源上限
stream 模块处理的是纯 TCP 连接(如数据库代理、Redis 透传、游戏服务器转发),每个连接至少占用 1 个文件描述符。若 worker_connections 设为 16384,但系统对 nginx 用户的 ulimit -n 仍是默认 1024,那实际生效的就是 1024 —— 其余连接会被静默丢弃。
- 永久设置:在
/etc/security/limits.conf中添加(替换nginx为实际运行用户,如www-data):nginx soft nofile 65536nginx hard nofile 65536 - 同时在
nginx.conf的主配置块中写明:worker_rlimit_nofile 65536; - 验证方式:
cat /proc/$(pgrep nginx)/limits | grep "Max open files",确认Max open files行的 soft 和 hard 值都 ≥ 你期望的worker_connections × worker_processes
匹配内核 accept 队列长度(关键!)
stream 模块监听端口时,内核为每个 listen() socket 维护一个“已完成三次握手、等待 accept()”的队列,长度由 net.core.somaxconn 控制。如果这个值太小(如默认 128),瞬时建连高峰会直接丢包——客户端表现为连接超时,Nginx 日志里却看不到任何记录。
- 计算依据:
somaxconn ≥ worker_connections / worker_processes,并留余量。例如 4 核机器配worker_processes 4、worker_connections 16384,则单 listen socket 需承载约 4096 个待取连接,somaxconn至少设为8192或16384 - 同步调整
net.ipv4.tcp_max_syn_backlog(未完成连接队列),建议设为somaxconn的 2 倍,防止 SYN 包被内核丢弃 - 生效命令:
sysctl -w net.core.somaxconn=16384,并写入/etc/sysctl.conf永久保存
stream 块内必须启用高效事件机制
stream 模块不走 HTTP 流程,对事件模型更敏感。若未显式指定,Nginx 可能回退到低效的 select,触发 1024 连接硬限制。
- 确保全局
events块中配置:use epoll;multi_accept on;accept_mutex on;(默认开启,保持即可) -
multi_accept on让单次事件循环尽可能多地从内核队列中取出连接,大幅降低队列积压概率,尤其适合短连接密集转发场景(如 MySQL 连接池穿透) - 避免在
stream上滥用keepalive_timeout:TCP 层无请求复用概念,长连接保持靠业务自身,Nginx 侧只需保证连接不被误杀即可
验证与典型配置示例
一个面向 Redis 集群代理的 stream 配置片段:
worker_processes auto;
worker_rlimit_nofile 65536;
<p>events {
use epoll;
worker_connections 16384;
multi_accept on;
}</p><p>stream {
upstream redis_cluster {
server 10.0.1.10:6379 max_fails=3 fail_timeout=30s;
server 10.0.1.11:6379 max_fails=3 fail_timeout=30s;
keepalive 1000; # stream 级 keepalive,复用后端连接
}</p><pre class='brush:php;toolbar:false;'>server {
listen 6380 so_keepalive=on;
proxy_pass redis_cluster;
proxy_timeout 1s;
proxy_responses 1;
}}
该配置配合 somaxconn=16384、ulimit -n 65536,可稳定支撑数万并发 TCP 连接转发。压测时重点观察 ss -s 输出中的 tcp 部分,确认 synrecv 和 estab 数量是否平稳增长,而非卡在某个阈值附近波动。


















