排查tcp重传超时故障需先确认“包发出但无响应”,再通过tcpdump抓包比对两端seq重复与rto间隔定位触发端;必须客户端和服务端同时抓包,结合netstat、/proc/net/snmp和ethtool指标交叉验证,将现象归因为具体网络或系统问题。

排查TCP重传超时故障,核心是确认“包发出去了但没收到响应”,再定位重传发生在哪一端、由谁触发、是否持续发生。tcpdump能直接看到SYN重传、数据段重传、ACK丢失引发的重复发送等真实行为,比日志和监控更底层、更可信。
抓包前先明确关键信息
别急着敲命令,先快速确认三件事:
- 问题端点:是客户端发不出?还是服务端收不到/不回?需在对应机器上抓包
- 目标地址和端口:比如
10.10.20.5:3306或api.example.com:443,不确定就先抓tcp port 3306这类范围 - 复现方式:能否稳定触发?建议用
curl、nc -vz或业务请求手动复现,边操作边抓包
用精准过滤快速捕获重传行为
重传不是靠肉眼找“Retransmission”字样——那是Wireshark解析后的标签,tcpdump终端输出里没有。你要盯的是**相同序列号(seq)的重复TCP段**,以及**时间间隔符合RTO规律的重发**。
- 抓SYN重传(连接建立失败):
sudo tcpdump -i eth0 -nn -s 0 'host 10.10.20.5 and port 3306 and tcp[tcpflags] & (tcp-syn) != 0'
如果看到多个[S]且源端口相同、目的IP/端口一致、时间间隔约1s/3s/7s(典型RTO指数退避),说明客户端在反复尝试握手 - 抓数据段重传(已建连后丢包):
sudo tcpdump -i eth0 -nn -s 0 'host 10.10.20.5 and port 3306 and tcp and not tcp[tcpflags] & (tcp-syn|tcp-fin|tcp-rst)'
重点关注seq值重复出现的数据包,尤其当后续包的ack没推进、或同一seq隔几百毫秒又出现 - 加时间戳辅助判断:
加上-tttt显示完整时间,方便算间隔;加-X可看载荷(如HTTP头),确认是不是同一请求被重发
对比两端抓包锁定问题位置
单端抓包只能看到“自己发了什么”或“自己收到了什么”,无法判断中间是否丢包。必须客户端和服务端同时抓,再比对:
- 若客户端发出SYN,服务端
tcpdump完全没看到→问题在链路中(防火墙、安全组、路由、网卡驱动丢包) - 若服务端收到SYN并回了SYN-ACK,但客户端没收到→SYN-ACK被中间设备拦截或丢弃
- 若双方都看到数据包,但服务端回的ACK迟迟不到客户端→ACK丢了,客户端会重传数据;此时服务端可能已处理完请求,却因没收到ACK而不断重发FIN或等待
- 用
tcpdump -r file.pcap -nn | head -20快速查看文件开头,确认关键包是否存在
结合系统指标交叉验证
tcpdump发现重传后,要立刻查系统层面是否佐证:
- 运行
netstat -s | grep -i "retran",看TCP retransmits计数是否突增 - 检查
/proc/net/snmp中Tcp:行的RetransSegs值 - 用
ethtool -S eth0 | grep rx_查rx_dropped、rx_errors,确认是否网卡层丢包 - 若
rx_dropped高,可能是中断风暴、ring buffer太小或CPU软中断处理不过来
重传本身是TCP的容错机制,真正要揪的是“为什么总得重传”。tcpdump给出的是现象,结合过滤、双端比对和系统指标,才能把“网络不稳定”的模糊结论,变成“SLB丢SYN-ACK”或“客户端网卡ring buffer溢出”这样的确定性判断。











