全连接队列溢出次数可通过netstat -s | grep -i "listen.*overflow"查看,重点关注“xxx times the listen queue of a socket overflowed”这一行,该数值为累计溢出次数,持续增长表明accept()处理慢或somaxconn过小。

怎么用 netstat -s 看全连接队列溢出次数
全连接队列(accept queue)溢出会在内核统计中留下明确计数,netstat -s 是最直接的观测方式。执行:netstat -s | grep -i "listen.*overflow"
重点关注两行输出:
-
XXX times the listen queue of a socket overflowed—— 这是全连接队列溢出总次数,数字持续增长说明应用accept()太慢或somaxconn设得太小 -
YYY SYNs to LISTEN sockets dropped—— 这个值**不是**半连接队列溢出,而是全连接队列满后、客户端重传 SYN 时被丢弃的次数(源码里归在LINUX_MIB_LISTENDROPS)
注意:netstat -s 输出的是累计值,需间隔几秒重复执行,观察数字是否上升。若每秒增加几十次,基本可判定 accept 队列已持续打满。
为什么 dmesg | grep "listen queue overflow" 更可信
netstat -s 统计依赖 SNMP 计数器,而 dmesg 记录的是内核实时打印的告警,不经过聚合,时间精度更高、无遗漏风险。运行:
dmesg | grep "TCP: listen queue overflow"
只要看到输出,就代表**此刻发生了全连接队列溢出丢包**。常见场景包括:
- Java 应用未配置
acceptCount(Tomcat 默认 100),且并发突增 - Nginx 的
listen ... backlog=xxx值小于系统somaxconn,实际生效取较小值 - Go net/http server 启动时未显式设置
net.ListenConfig.Backlog,沿用内核默认值(常为 128)
该日志不会自动清空,但内核环缓冲区有大小限制,高频溢出时可能被覆盖,建议搭配监控轮询采集。
ss -lnt 显示的 Recv-Q 和 Send-Q 怎么读
ss -lnt 每行输出形如:LISTEN 0 128 *:80 *:*
-
Recv-Q列(这里是0):当前全连接队列中已建立但尚未被应用accept()取走的连接数 -
Send-Q列(这里是128):该监听 socket 的全连接队列最大长度,取somaxconn与应用调用listen(fd, backlog)时传入值的较小者
如果某端口长期显示 Recv-Q 接近甚至等于 Send-Q(比如 127 128),说明队列几乎满载,再有新 ACK 就会触发溢出。这不是报警,而是**即将溢出的明确信号**。
半连接队列溢出不能靠 netstat -s 准确判断
很多资料误把 netstat -s 中的 SYNs to LISTEN sockets ignored 当作半连接队列溢出,这是错的。该计数实际反映的是:
- SYN 包到达时,半连接队列已满 +
tcp_syncookies=0,内核选择静默丢弃 - 或 SYN 包校验失败、IP 伪装等异常情况
真正可靠的半连接队列溢出证据只有两个:
-
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触发了防护机制
半连接队列问题往往伴随客户端连接超时(而非 connection refused),排查时别被错误指标带偏。











