必须分层监控TCP队列溢出:半连接队列溢出看SynsToListenDrops和ss -n state syn-recv,全连接队列溢出看ListenOverflows、ss -lnt的Recv-Q/Send-Q,Socket缓冲区溢出查TcpRcvQDrop,并辅以dmesg和tcpdump交叉验证。

Linux 系统中 TCP 队列溢出不是单一现象,而是分层发生的:半连接队列(SYN Queue)满导致 SYN 包被丢,全连接队列(Accept Queue)满导致 ESTABLISHED 连接被拒绝。监控必须分层定位,不能只看一个数字。
查半连接队列溢出:SynsToListenDrops
这是最直接的指标,代表内核因 SYN 队列满而丢弃的 SYN 包数:
- 执行 awk '/^TcpExt/ {print $1,$2}' /proc/net/snmp | grep SynsToListenDrops,输出值持续增长即确认溢出
- 注意:该计数仅在 tcp_syncookies = 0 时可靠;若启用了 SYN Cookie(默认常为1),此值可能不涨,但代价是连接状态信息丢失
- 配合 ss -n state syn-recv | wc -l 查看当前 SYN_RECV 数量,对比 cat /proc/sys/net/ipv4/tcp_max_syn_backlog 判断是否接近上限
查全连接队列溢出:ListenOverflows
该指标反映 accept 队列已满、三次握手完成却无法入队的次数:
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
- 同样从 /proc/net/snmp 中提取:awk '/^TcpExt/ {print $1,$2}' /proc/net/snmp | grep ListenOverflows
- 比对 ss -lnt 输出中的 Recv-Q(当前排队数)与 Send-Q(队列上限),若 Recv-Q 长期 ≥ Send-Q,说明应用 accept() 太慢或队列太小
- Send-Q 实际生效值 = min(应用 listen() 传入的 backlog, net.core.somaxconn),两者需同步调高
查 Socket 级缓冲区溢出:TcpRcvQDrop
这不是连接队列问题,而是已建立连接的接收缓冲区满导致的数据段丢弃:
- 执行 grep Tcp /proc/net/snmp | awk '{print $19}',第19列即 Tcp: RcvQDrop
- 该值只增不减,重启清零;业务高峰期跳升,说明应用读取速度跟不上收包速度
- 注意:它和 netstat -s 中的 “packet receive errors” 无关——后者统计的是 IP 层/驱动层错误(如校验失败、DMA 溢出),不是 socket 缓冲区满
辅助验证手段
单靠计数器不够,需结合实时状态和日志交叉印证:
- dmesg | grep -i "possible SYN flooding":内核检测到半连接异常堆积并触发防护时会打印此日志
- ss -s:查看全局统计,“SYN-RECV” 和 “ESTAB” 的比例失衡可提示队列瓶颈位置
- tcpdump -i any 'tcp[tcpflags] & tcp-syn == tcp-syn and dst port X':抓包观察是否有大量 SYN 无响应,排除网络中间设备拦截可能

















