tcp_max_syn_backlog管控syn半连接队列,即客户端发来syn包后、完成三次握手前的缓冲区;其值须≥net.core.somaxconn且匹配nginx listen backlog,否则被截断失效。

调优 tcp_max_syn_backlog 能直接增强 Nginx 在流量突增时的连接接纳能力,关键在于不让建连请求在“握手前”就被丢弃。
它管的是哪一环?
客户端发来 SYN 包,内核收到后不立即交给 Nginx,而是先放进一个叫“SYN 半连接队列”的缓冲区,等客户端返回 ACK 完成三次握手后,才移到 accept 队列供 Nginx 的 worker 进程调用 accept()。这个缓冲区的上限就是 tcp_max_syn_backlog。
如果突发大量新连接(比如秒级 3000+),而该值还是默认的 1024,哪怕 Nginx 自身很空闲、CPU 和带宽都充足,也会在第一关就静默丢包——客户端收不到 SYN-ACK,只能重试或超时,表现为“连接慢”“大量 timeout”“ss -s 显示 SYN_RECV 持续堆积”。
怎么设才有效?
不能孤立调整,必须和两个参数对齐:
- net.core.somaxconn:控制 accept 队列(已完成握手、等待被 Nginx 接收的连接)长度,建议设为 65535 或 262144;
-
Nginx listen backlog:例如
listen 80 backlog=65535;,该值不能超过somaxconn,否则会被内核自动截断; -
tcp_max_syn_backlog 应 ≥
somaxconn,常见生产值是 65535 或 262144;小内存机器可从 32768 起步。
三者不匹配,调了也白调。比如只改 tcp_max_syn_backlog 到 65535,但 somaxconn 还是 128,那 accept 队列会先满,导致已握手成功的连接卡住,错误日志里可能出现 “no live upstreams” 或 “connection reset by peer”。
别依赖 syncookies 当救火员
Linux 默认开启 tcp_syncookies=1,队列满时会启用 syncookie 机制,绕过队列限制完成建连。但这不是优化,是兜底:
- 增加 CPU 开销(每次计算 cookie);
- 不支持 TCP 时间戳、SACK 等扩展功能;
- 掩盖真实瓶颈,让问题更难定位。
应关闭 syncookies(sysctl -w net.ipv4.tcp_syncookies=0)并真正调大 tcp_max_syn_backlog,才能稳定扛住真实业务突发。
验证是否生效
改完后运行以下命令确认:
-
sysctl net.ipv4.tcp_max_syn_backlog—— 看是否为你设的值; -
ss -s | grep "SYN"—— 观察 SYN_RECV 数量是否回落、不再持续高位; -
netstat -s | grep -i "listen\|drop"—— 检查ListenOverflows和ListenDrops是否归零或显著下降。
配合压测工具(如 wrk 或 hey)模拟短时高建连 QPS,观察连接成功率和首包延迟变化,比单纯看参数更有说服力。











