Nginx高并发TCP代理性能瓶颈在内核队列协同,需同步调优net.ipv4.tcp_max_syn_backlog(半连接队列)、net.core.somaxconn(全连接队列)及worker_connections,否则连接在建连阶段即被内核丢弃。

worker_connections 和 TCP 半连接队列(由 net.ipv4.tcp_max_syn_backlog 控制)不是同一层的机制,但必须协同调优——否则连接会在到达 Nginx 前就被内核丢弃,根本不会触发 worker_connections 的作用。
半连接队列是建连第一道卡口
当客户端发起 SYN,服务端回复 SYN-ACK 后,连接进入 SYN_RECV 状态,暂存在半连接队列中,等待三次握手完成并移入全连接队列。这个队列长度由 tcp_max_syn_backlog 决定。
- 若该值过小(如默认 128 或 1024),突发大量建连请求时,新 SYN 包会被内核直接丢弃,客户端表现为超时、重传失败或 Connection refused
- 它和
net.core.somaxconn是上下游关系:半连接队列满 → 无法完成握手 → 全连接队列(somaxconn)始终收不到新连接 - 建议值设为 ≥
net.core.somaxconn,生产环境统一设为 65535
worker_connections 只管“已建立”的连接
worker_connections 控制每个 worker 进程能同时处理的已进入 ESTABLISHED 状态的连接数,属于应用层调度能力。它对半连接阶段完全无感知。
- 哪怕你设了
worker_connections 65535,只要半连接队列堵死,连接压根进不来,这个配置就形同虚设 - 验证是否被半连接瓶颈卡住:运行
ss -s | grep "TCP:",观察synrecv数值是否持续高位;或用netstat -s | grep -i "listen overflows"查看溢出计数 - 注意:Nginx 的
listen ... backlog=参数只影响单个 socket 的全连接队列长度,不改变半连接队列,后者纯由内核参数控制
必须同步调整的配套动作
光调高两个参数还不够,需打通从网卡到 Nginx 进程的整条链路:
- 启用
net.ipv4.tcp_syncookies = 1:在半连接队列满时启用 Cookie 机制,避免轻量级 SYN Flood 导致合法连接被拒 - 扩大本地端口范围:
net.ipv4.ip_local_port_range = "1024 65535",缓解代理场景下的端口耗尽 - Nginx stream 模块代理 TCP 服务(如 Redis/MySQL)时,同样适用——每个
listen指令背后都依赖同一套内核队列机制 - 搭配
use epoll;和multi_accept on;,让 worker 更快地从全连接队列中取走连接,减少积压传导回半连接队列
典型配置组合示例
假设你有 4 个 worker 进程,目标支撑 32k 并发连接:
worker_processes 4;events { worker_connections 8192; use epoll; multi_accept on; }-
worker_rlimit_nofile 65536;(≥ 4 × 8192) net.core.somaxconn = 65535net.ipv4.tcp_max_syn_backlog = 65535-
net.core.netdev_max_backlog = 262144(应对网卡收包洪峰)


















