Linux内核无主动“三次握手队列报警”,仅通过TcpExtListenDrops等统计计数器(如“SYNs to LISTEN sockets dropped”)反向推断SYN队列溢出;启用tcp_syncookies后该值不增但SyncookiesSent上升,表明内核绕过队列限制。

Linux 没有“三次握手队列报警”这个机制
Linux 内核本身不会主动触发“报警”——它不发邮件、不写日志、不调用钩子函数来通知你 syn backlog 溢出了。所谓“报警”,其实是通过监控指标异常或丢包现象反向推断出来的。真正能观察到的,只有队列满导致的 SYN 包被丢弃这一结果。
怎么确认 syn backlog 队列是否溢出
关键看内核统计的丢包计数器:Syncookies 启用时行为不同,但无论是否启用,TcpExtListenOverflows 和 TcpExtListenDrops 是最直接的证据:
-
TcpExtListenOverflows:表示accept queue(全连接队列)溢出次数 —— 注意,这不是三次握手队列(即syn queue),但常被误认 -
TcpExtListenDrops:表示因syn queue或accept queue满,且未启用syncookies时,直接丢弃SYN的次数(更贴近“三次握手失败”) - 启用
net.ipv4.tcp_syncookies = 1后,TcpExtListenDrops通常不增,但TcpExtSyncookiesSent会上升 —— 这说明内核在用 cookie 抗 SYN Flood,不是“没报警”,而是“悄悄绕过了队列限制”
查看命令:
cat /proc/net/netstat | grep -i "ListenDrops\|ListenOverflows" # 或更直接: ss -s | grep -i "synrecv\|listen"
netstat -s 和 ss -s 输出怎么看
netstat -s 已逐渐被弃用,ss -s 更轻量、数据来源更接近内核实时统计。重点关注这几行:
-
56098 SYNs to LISTEN sockets dropped→ 对应TcpExtListenDrops,是三次握手阶段丢SYN的铁证 -
1234 times the listen queue of a socket overflowed→ 对应TcpExtListenOverflows,是accept queue溢出,发生在三次握手完成之后 -
SYN-RECV状态连接数长期 > 0 且波动剧烈?说明客户端没发ACK(可能是网络问题或攻击),也挤压syn queue
注意:ss -lnt 只显示监听端口,不反映队列长度;要查单个端口的队列实际使用情况,得看 /proc/net/rt_cache 或用 bpftrace 抓 tcp_conn_request,但日常运维中基本靠统计值反推。
为什么调大 net.core.somaxconn 不一定管用
很多人以为改了 net.core.somaxconn 就能解决“三次握手队列满”,其实它只控制 accept queue 上限,而 syn queue 大小由 min(net.ipv4.tcp_max_syn_backlog, somaxconn) 决定(Linux 5.4+ 还受 net.core.netdev_max_backlog 影响)。常见误区:
- 只改
somaxconn,没同步调高tcp_max_syn_backlog→syn queue仍卡在默认值(通常是 128 或 256) - 应用层
listen(fd, backlog)参数设得太小(如传 1),会覆盖内核限制,实际队列比somaxconn还小 - 云环境(如 AWS ENA、Azure Accelerated Networking)下,中断聚合或 RSS 分布不均,可能导致某个 CPU 的
syn queue局部打满,而全局统计不明显
验证是否生效:
echo 'net.ipv4.tcp_max_syn_backlog = 65535' >> /etc/sysctl.conf echo 'net.core.somaxconn = 65535' >> /etc/sysctl.conf sysctl -p # 然后重启服务(必须重 exec listen() 才能应用新 backlog)
真正难定位的是:丢包发生在网卡驱动、XDP 层、还是 TCP 入口?TcpExtListenDrops 只告诉你“丢了”,但不告诉你是被 iptables DROP、被 tc ingress 限速丢,还是真因为队列满。这时候得结合 perf trace -e 'tcp:tcp_receive_reset' 或 bpftool prog list 看有没有干扰程序。


















