最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Linux TCP 协议栈内发送队列(Send-Q)溢出排查
时间:2026-07-13 08:38:01 编辑:袖梨 来源:一聚教程网
Linux TCP发送队列(Send-Q)溢出本质是套接字发送缓冲区满,导致send/write阻塞或返回EAGAIN;它属传输层缓冲问题,需从应用吞吐、对端接收能力及网络路径协同排查,区别于SYN/accept队列溢出。
Linux TCP 发送队列(Send-Q)溢出,本质是套接字的 发送缓冲区已满,导致内核无法继续缓存待发数据,应用调用 send() 或 write() 可能阻塞或返回 EAGAIN/EWOULDBLOCK。它不同于半连接队列(SYN Queue)或全连接队列(Accept Queue)溢出,属于传输层缓冲行为,需从应用吞吐、对端接收能力和网络路径三方面定位。
确认 Send-Q 是否真实堆积
Send-Q 值在 ss -an 或 netstat -an 输出中仅对 非 LISTEN 状态连接 有效,含义是“已发出但尚未被对端 ACK 确认的数据字节数”。持续高位(如 >100KB)且不回落,才提示潜在问题:
- 运行
ss -tni 'sport == :80' | awk '$2 > 100000 {print $0}'筛选 Send-Q 超 100KB 的 ESTABLISHED 连接 - 对比同一连接的
rtt和rttvar:若 RTT 显著增大(如 >500ms)、RTT 方差飙升,说明对端接收慢或网络丢包,导致窗口停滞、重传堆积 - 检查对端是否异常:如客户端崩溃、防火墙拦截 ACK、中间设备限速,都会造成发送端缓冲区持续积压
排查内核级 TCP 发送缓冲区丢包
Send-Q 溢出的最终表现是内核主动丢弃新数据包,指标为 tcpRcvQDrop(注意不是 packet receive errors):
- 执行
grep Tcp /proc/net/snmp | awk '{print $19}'获取tcpRcvQDrop计数;该值非零且持续增长,说明 socket 接收队列满导致丢包——但这反映的是本端接收队列满,间接影响对端 Send-Q;真正对应本端发送丢包的是Tcp: InCwndFull(拥塞窗口满)或驱动层 drop,需结合/proc/net/dev中对应网卡的drop字段交叉验证 - 若
ss -i显示某连接cwnd长期为 1 MSS 且ssthresh极低,大概率触发了拥塞控制降窗,发送速率被压制,缓冲区易堆积
检查应用层写入行为与 socket 配置
Send-Q 高往往源于应用未及时感知对端窗口关闭,或自身写入节奏失控:
- 确认 socket 是否启用
TCP_NODELAY:若业务为小包高频交互(如 RPC),禁用 Nagle 算法可减少缓冲等待,避免小包攒批加重 Send-Q 压力 - 检查应用是否忽略
send()返回值:当返回值< len时,必须循环调用直到写完,否则残留数据滞留在内核缓冲区 - 观察
SO_SNDBUF设置:默认值通常 128KB~256KB,若业务需突发大块数据(如文件上传),可适当调大(setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &val, sizeof(val))),但需同步调整net.ipv4.tcp_wmem
关联网络路径与对端状态
单看本机 Send-Q 无法闭环定位,必须协同分析链路两端:
- 用
tcptrace或Wireshark抓包,重点观察:是否有大量重复 ACK(对端丢包)、窗口字段是否长期为 0(对端接收缓冲区满)、是否存在持续重传(超时未 ACK) - 检查对端主机:
ss -tni看其 Recv-Q 是否持续 >0,cat /proc/net/snmp | grep Tcp:查tcpRcvQDrop是否增长——若对端接收队列满,本端 Send-Q 必然堆积 - 排查中间设备:运营商 QoS、云厂商安全组限速、硬件负载均衡器缓冲区设置,都可能导致 ACK 延迟或丢弃,诱发本端发送停滞
相关文章
- 尽管工作室已关闭:Wreckreation 2 仍正式公布:距离前作发布仅九个月 07-22
- 率土之滨武将强度排行 率土之滨武将开荒搭配攻略表 07-22
- 挖掘者米娜怎样召唤伙伴成就攻略分享 07-22
- 仙灵物语最强阵容搭配攻略:仙灵物语高战力阵容推荐与实战解析 07-22
- 天堂2盟约怎么升级快:天堂2盟约快速升级技巧与高效练级指南 07-22
- 《幻兽帕鲁》世界树内部进入方法介绍 07-22