确认syn队列溢出需查netstat -s中“listen overflows”或/proc/net/snmp中synstolistendrops增长、ss统计syn-recv数接近tcp_max_syn_backlog、dmesg出现“possible syn flooding”;协同调大tcp_max_syn_backlog与somaxconn至一致值,启用tcp_syncookies,并匹配应用层listen backlog。

解决 SYN 队列溢出,核心是让内核能容纳更多未完成三次握手的连接请求,同时避免丢包和拒绝服务。光调一个参数往往无效,必须协同调整、验证并匹配应用行为。
确认是否真发生了 SYN 队列溢出
别直接改配置,先看证据:
- 查内核丢包统计:netstat -s | grep -i "listen overflows" 或 awk '/^TcpExt/ {print $1,$2}' /proc/net/snmp | grep SynsToListenDrops —— 数值持续增长就是明确信号
- 看当前半连接数:ss -n state syn-recv | wc -l,再对比 cat /proc/sys/net/ipv4/tcp_max_syn_backlog,若前者长期接近后者,说明队列已满
- 检查内核日志:dmesg | grep -i "possible SYN flooding",出现该提示通常意味着队列满且 tcp_syncookies=0
同步调高两个关键队列参数
SYN 队列(半连接队列)实际大小由两个参数共同决定,必须设为一致,否则会被较小值截断:
- net.ipv4.tcp_max_syn_backlog:显式控制每个监听端口的 SYN 队列长度
- net.core.somaxconn:虽主要管全连接队列,但在多数内核版本中也隐式约束 SYN 队列上限
建议统一设为 4096(中小并发)或 65535(高并发),写入配置:
echo "net.ipv4.tcp_max_syn_backlog = 4096" >> /etc/sysctl.conf
echo "net.core.somaxconn = 4096" >> /etc/sysctl.conf
sysctl -p
开启 tcp_syncookies 作为兜底防护
即使队列调大,突发流量仍可能瞬间打满。启用 SYN Cookie 可在不增加内存开销的前提下临时绕过队列限制:
- 执行 echo "net.ipv4.tcp_syncookies = 1" >> /etc/sysctl.conf
- 运行 sysctl -p 生效
- 注意:它不支持 SACK 等高级 TCP 特性,但对普通 HTTP/HTTPS 流量无影响,生产环境建议始终开启
检查并匹配应用层 listen backlog
内核参数再大,如果应用自己调用 listen(fd, backlog) 时传的值太小,最终队列仍被卡住:
- Nginx:需在 listen 80 backlog=4096; 中显式声明
- uWSGI:通过 --listen 4096 设置
- Spring Boot(Tomcat):配置 server.tomcat.accept-count=4096
- Go/Python 启动服务时,若支持 backlog 参数,也要设为相同值











