Nginx TCP代理高并发争用通过内核队列、stream调度、upstream连接池三层协同解决:调优somaxconn等内核参数防丢包;保持accept_mutex on+multi_accept on实现串行批量连接获取;upstream启用keepalive复用连接,并配合超时与监控防积压。

Nginx 的 TCP 代理(stream 模块)处理高并发连接争用,核心不是让多个 worker “抢”连接,而是从内核层、Nginx 调度层、上游连接池三层协同消解争用源头——避免排队、减少建连、隔离资源。
内核队列必须撑住握手洪峰
TCP 代理争用常始于连接刚建立阶段:大量 SYN 到达时,若内核连接队列溢出,就会静默丢包,客户端反复重试,反而加剧争用。关键参数需对齐:
-
net.core.somaxconn = 65535:监听全连接队列上限,必须 ≥ Nginx listen 的 backlog 值(如
listen 8443 backlog=65535) - net.ipv4.tcp_max_syn_backlog = 65535:SYN 半连接队列容量,应对突发握手,低于 somaxconn 会导致 SYN 包被丢弃
- net.core.netdev_max_backlog = 262144:网卡软中断收包队列,防止高速入包但内核处理不过来而丢包
stream 层连接调度要串行+批量
Nginx 默认开启 accept_mutex on,它让 worker 进程串行获取新连接,杜绝“惊群”——所有 worker 同时唤醒却只有一人能处理,其余空转耗 CPU。这不是性能瓶颈,而是稳定性基础:
- 保持
accept_mutex on,不建议关闭;若观察到accept() failed (24: Too many open files),应先调高系统文件描述符限制,而非关互斥锁 - 搭配
multi_accept on:抢到锁的 worker 一次性接收多个就绪连接,提升单次调度吞吐 - 确保
worker_rlimit_nofile和系统ulimit -n一致(如 65535),否则即使队列畅通也会因句柄不足触发拒绝或重试争用
复用 upstream 连接池,从源头减压
TCP 代理争用很大比例来自频繁向后端建连(如 Redis 查询、MySQL 小事务)。stream 模块支持 upstream 级连接复用,这才是真正的减负关键:
- 在 upstream 块中配置
keepalive 32(建议设为后端单机处理能力的 1/2~1/3),维持空闲连接供复用 - 配
keepalive_timeout 60s控制保活时长,避免僵死连接长期占位 - 显式声明
proxy_buffering off(stream 默认关闭,但显式写明更安全),防止缓冲延迟或粘包干扰复用逻辑 - 客户端侧需配合:使用连接池客户端(如 Netty ChannelPool)、避免 DNS 轮询导致误断连、禁用过短的超时设置
主动释放与可观测性防积压
争用往往由少数长连接或慢响应拖累全局。需通过超时控制和监控快速识别并清理:
-
proxy_timeout 30s设为合理值,比后端实际处理时间略宽裕,但不过长;避免连接卡在 proxy 阶段不释放 - 用
ss -s查看 TIME-WAIT 占比,超 15% 就说明端口回收慢,需检查tcp_tw_reuse = 1是否生效、ip_local_port_range是否扩到1024 65535 - 启用 stream stub_status 或 Prometheus metrics,重点关注
stream_upstream_connections_active和idle比例;若 active 长期接近 keepalive 上限,说明池子不够或后端响应慢


















