高并发下tcp半连接队列满本质是建连请求速率远超处理能力,导致合法syn包静默丢弃,表现为客户端超时重传、服务端无错误日志;须通过netstat/ss/dmesg验证溢出,同步调大tcp_max_syn_backlog、somaxconn及nginx listen backlog至65535,启用tcp_syncookies=1并设tcp_synack_retries=3,辅以iptables限速和连接复用。

高并发下 TCP 半连接队列(SYN Queue)满,本质是建连请求涌入速度远超 Nginx 和内核处理能力,导致合法 SYN 包被静默丢弃——现象是客户端连接超时、重传,服务端却无明显错误日志。这不是单点问题,必须从内核、Nginx 配置、流量防护三层联动调优。
确认是否真发生半连接队列溢出
别靠猜测,用指标验证:
- 执行 netstat -s | grep -i "listen overflows\|SYNs to LISTEN",若数值持续增长,说明已发生溢出
- 查当前半连接数:ss -n state syn-recv | wc -l,再对比 cat /proc/sys/net/ipv4/tcp_max_syn_backlog,接近或超过即为瓶颈
- 看内核日志:dmesg | grep -i "possible SYN flooding",出现该提示说明触发保护但未启用兜底机制
同步调大三个关键队列上限
SYN 队列、ACCEPT 队列、Nginx listen backlog 必须匹配,缺一不可:
- 设 net.ipv4.tcp_max_syn_backlog = 65535(控制半连接队列长度)
- 设 net.core.somaxconn = 65535(控制全连接队列上限,必须 ≥ tcp_max_syn_backlog)
- Nginx stream 块中监听配置加 listen 12345 backlog=65535(确保应用层能真正使用该容量)
启用 SYN Cookies 并压缩握手重试
这是队列满时最可靠的兜底方案,不占内存,自动切换为无状态响应:
- 开启:sysctl -w net.ipv4.tcp_syncookies=1,并写入 /etc/sysctl.conf 持久化
- 验证生效:sysctl net.ipv4.tcp_syncookies 返回 1,且 netstat -s | grep -i "syncookies sent" 计数持续上升
- 降低重试次数:net.ipv4.tcp_synack_retries = 3(默认 5),减少无效重传压力
配合网络层防护与连接复用
光调参数不够,还需阻断无效流量、减少建连频次:
- 用 iptables 对高频 IP 限速,例如每秒最多 50 个新连接:-A INPUT -p tcp --syn -m limit --limit 50/sec -j ACCEPT
- 关闭非必要端口,缩小攻击面;前置反代或 CDN 复用长连接,降低直达 Nginx 的建连压力
- 在 stream upstream 中启用 keepalive 32,复用后端连接,避免短连接反复建连加剧队列负担











