调优 net.core.somaxconn 是为打通 TCP 三次握手完成到 Nginx accept 的关键通路,其控制每个 listen socket 的已完成握手但未 accept 的连接队列长度,需与 Nginx listen backlog 对齐(取 min 值),并同步调优 tcp_max_syn_backlog、netdev_max_backlog、file-max 等全链路参数。
调优 net.core.somaxconn 不是为了“堆数值”,而是打通从 TCP 三次握手完成到 Nginx 成功 accept 的关键通路。瞬间高并发握手(如秒杀、活动开抢、CDN 回源洪峰)下,连接卡在内核队列却无法被取走,就会表现为响应延迟、超时、502/503,而日志里完全看不到请求痕迹——问题不在 Nginx 处理慢,是连接根本没进来。
它控制的是每个 listen() socket 对应的“已完成三次握手、但尚未被 Nginx 调用 accept() 取走”的连接队列长度(即 accept queue)。这个队列一满,后续合法连接会被内核静默丢弃:不发 RST,也不回 ACK,客户端只能重传、超时、最终失败。默认值 128 或 1024,在数千并发握手时就可能打满。
实际生效的队列长度是 min(net.core.somaxconn, Nginx listen backlog)。只改内核不改 Nginx,等于白调:
server{} 块中显式声明,例如:listen 80 backlog=65535; 或更高(如 131072)listen 443 ssl backlog=65535;
ss -lnt | grep ':80',看第四列第二个数是否为你设置的值不能盲目设大,需结合服务器配置和瞬时峰值估算:
worker_connections ÷ worker_processes × 1.5~2
worker_processes 8、worker_connections 65535 → 单端口理论待 accept 连接约 8200 → 推荐设为 131072(应对分布不均与毛刺)262144 或 524288
/etc/sysctl.conf,再执行 sudo sysctl -p
单点调大 somaxconn 效果有限,上下游环节必须跟上:
net.ipv4.tcp_max_syn_backlog:控制半连接队列(SYN_RECV),建议设为 somaxconn 的 1~2 倍(如 524288)net.core.netdev_max_backlog:网卡软中断收包队列,防突发丢包,推荐 262144
fs.file-max 和 ulimit -n:系统级文件描述符上限需 ≥ worker_processes × worker_connections × 1.5,并用 worker_rlimit_nofile 同步给 Nginx 进程net.ipv4.tcp_tw_reuse = 1:启用 TIME-WAIT 复用,缓解短连接爆发下的端口耗尽events 块中启用 multi_accept on;:让单次事件循环尽可能多地从队列中取走就绪连接