要让系统真正扛住大规模瞬间高并发tcp握手,net.core.somaxconn必须与nginx listen backlog严格对齐(取min值),并同步调优tcp_max_syn_backlog、netdev_max_backlog、file-max及ulimit等全链路参数,否则已完成三次握手的连接将被内核静默丢弃。

要让系统真正扛住大规模瞬间高并发的 TCP 握手请求,net.core.somaxconn 不能孤立调整——它必须和 Nginx 的监听队列能力对齐,并打通 TCP 全链路缓冲。问题常不出在 Nginx 接收慢,而出在内核“接不住”已完成三次握手的连接,导致合法请求被静默丢弃(不发 RST,客户端只看到超时或重连失败)。
明确 somaxconn 的实际作用
它不是总连接数限制,而是每个 listen() socket 对应的“全连接队列”(accept queue)长度上限:TCP 三次握手完成后,连接就进入这个队列,等待 Nginx 调用 accept() 取走。默认值通常为 128 或 1024,在千级并发下就可能打满。队列一满,后续合法连接直接被内核丢弃,Nginx 日志里完全看不到痕迹。
与 Nginx listen backlog 严格对齐
实际生效的队列长度是 min(net.core.somaxconn, nginx listen backlog)。只改内核不改 Nginx,等于白调:
- 在
server{}块中显式声明:listen 80 backlog=65535;(HTTP)或listen 443 ssl backlog=65535;(HTTPS) - 避免依赖隐式默认值(旧版 Nginx 默认 backlog=511,新版仍可能未覆盖)
- 验证是否生效:
ss -ltn | grep ':80',观察第四列第二个数字(Send-Q)是否已更新为你设置的值
按负载推算合理数值并留余量
不能盲目设大,需结合 worker 分配估算理论下限:
- 若
worker_processes auto(如 8 核),worker_connections 65535,理论总并发约 52 万 - 假设仅监听 80/443 两个端口,单端口最坏需承载约 26 万待 accept 连接
- 推荐
net.core.somaxconn = 262144或524288(留足应对分布不均和瞬时毛刺) - 临时生效:
sudo sysctl -w net.core.somaxconn=524288 - 永久生效:在
/etc/sysctl.conf中添加net.core.somaxconn = 524288,再执行sudo sysctl -p
同步强化 TCP 全链路环节
只调 somaxconn 是单点优化,SYN 队列、网卡收包、文件描述符等任一环节卡住,都会导致连接在更早阶段丢失:
-
net.ipv4.tcp_max_syn_backlog = 524288:半连接队列(SYN queue),建议 ≥somaxconn -
net.core.netdev_max_backlog = 262144:网卡软中断收包队列,防突发流量丢包 -
fs.file-max = 655350:系统级最大文件描述符,需 ≥ 预期并发 × 1.5 -
ulimit -n 65535+worker_rlimit_nofile 65535:确保 Nginx 进程能实际使用到该限制 -
multi_accept on;:让单次事件循环尽可能多地从队列中取走就绪连接











