聊聊 wireshark 的重传包和重复包(Duplicate Packets or TCP Retransmissions?)
1 背景
最近某客户在推进全栈信创,其中操作系统使用了鲲鹏(arm)+麒麟V10,数据库使用了OceanBase, 大数据平台使用了星环TDH,JDK使用了龙井1.8。
在使用 datax 从 ob 同步数据到 hdfs 的过程中,我们发现 arm 版的 JDK 消耗的堆空间比 x86 的 JDK 大很多(400万数据,前者大概需要8G,而后者只需要2G)。
为分析原因,除了排查 JVM 堆栈信息,为排除网络影响,我们还通过 tcpdump 在 datax 节点进行抓包,并导出到 wireshark 中进行分析。
抓包命令如下:tcpdump -i any -nn -s 100 "port 2883 or port 8020" -w /tmp/ob.pcap;
2 现象-虚惊一场
将 pcap 包导出并使用 wireshark 打开后,在 "packet list"面板和“expert info” 中,都可以发现,wireshark 对大量的 TCP 数据包,都进行了“重传”,“快速重传”,“DUP ACK” 的标识,如下图所示:
- This frame is a (suspected) fast retransmission
- This frame is a (suspected) retransmission
- Duplicate ACK
因为这是使用了万兆网卡的 LAN 内网环境,wireshark 显示的 RTT 和 RTO 也都在几十微秒左右, 所以网络情况应该是良好的,如此多的重传包,严重不合理呀!
进一步在 “packet details”中,对比查看重传包/Duplicate ACK 和对应的原始包,才发现,这些包的除了 TCP SEQ/ACK 完全一致,IP Identifiation 也完全一致!虚惊一场,原来这些包是 Duplicate Packets,网络是没有问题的!
- 对于 “duplicate ip packet”,Wireshark 就经常错误诊断并标识为 "TCP Retransmission","TCP Fast Retransmission","TCP Spurious Retransmission" ,"TCP Out-of-Order",或 “Duplicate ACK”;
- 所以说,Wireshark 中的提示信息,也不一定任何时候都是正确的,我们不能无脑相信,而是需要结合 TCP 的工作机制,仔细甄别。
3 技术背景- TCP retransmition,Layer 3 loop, Layer 2 duplicate
以下三种包很容易引起混淆:
- TCP retransimition (一般是超时等网络问题);
- Layer 3 loop(三层网络环路,一般是网络拓扑和配置问题);
- Layer 2 duplicate (二层重复包,可能是网络端口镜像和linux cooked capture 抓包方式问题,当然也有可能是网络设备的软或硬件问题);
三者各自的特点和区别概括如下:
- TCP retransimition: TCP SEQ/ACK 一致,IP ID 不一致;(TCP层面遇到问题需要重传,此时TCP将包交给IP层后,IP层会封包并给与新的IP ID);
- Layer 3 loop:TCP SEQ/ACK 一致,IP ID 一致,但 TTL 不一致(三层网络环路,数据包传输过程中,每经过一跳,其ttl 值就会被路由器减1);
- Layer 2 duplicate:数据包所有字段完全一致,包括TCP SEQ/ACK,IP ID,以及 TTL;
4 如何清理去掉二层的重复包
当遇到了二层的重复包且底层原因是 linux cooked caputre等抓包方式引起的问题时,可以使用工具去掉重复包,此后 wireshark 显示的数据包就更清爽了,更方便进一步分析了。
安装 wireshark 时,一般也一并安装了 editcap 工具,可以使用该工具编辑并去掉 duplicate packet。该工具底层会对比指定大小窗口内所有数据包的MD5是否相同,若相同则丢弃重复的包:
- 示例命令如下:editcap.exe -d infile.pcap outfile.pcap
- 如果 editcap 默认的dup 窗口参数不合适,-D 和 -w 修改;