4. Wireshark 抓包分析吞吐测试:在 iPerf 测试中同步抓包、分析 TCP 窗口与重传、定位吞吐瓶颈
吞吐测试跑完了,数字看着挺漂亮。但你真的信吗?
我见过太多案例——iPerf 报告显示 900Mbps,实际业务跑起来只有 300M。问题出在哪?就在 TCP 的细节里。今天咱们就用 Wireshark 把 iPerf 的流量扒开看看。
4.1 为什么要在 iPerf 测试中同步抓包?
iPerf 本身只告诉你「发了多少数据」。它不告诉你:
- 数据包是不是在排队?
- 窗口是不是被卡住了?
- 有没有悄悄重传?
说白了,iPerf 是结果,Wireshark 是过程。我习惯在测试时两端同时抓包,这样能看清每一毫秒发生了什么。
4.2 抓包前的准备工作
别急着点开始。先做好三件事:
- 确认抓包位置——最好在客户端和服务端同时抓。如果条件有限,至少抓客户端侧。
- 设置过滤条件——只抓 iPerf 的端口,避免流量太大把 Wireshark 搞崩。
- 记录测试参数——iPerf 的窗口大小、线程数、测试时长,这些后面分析时都要用。
我曾经有一次忘了设过滤,抓了 5 分钟,文件 2GB 多。打开 Wireshark 直接卡死。嗯,从那以后我再也不敢偷懒了。
4.3 同步抓包的操作步骤
这里给出一套我常用的操作流程:
| 步骤 | 操作 | 说明 |
|---|---|---|
| 1 | 启动服务端 iPerf | iperf3 -s -p 5201 |
| 2 | 启动客户端 Wireshark | 过滤条件:tcp.port == 5201 |
| 3 | 启动客户端 iPerf | iperf3 -c 192.168.1.10 -t 30 -w 256K |
| 4 | 测试结束后停止抓包 | 保存为 pcapng 文件 |
| 5 | 服务端也抓一份 | 用于对比分析 |
tcp.analysis.flags 过滤,能快速定位所有异常包——重传、重复 ACK、窗口零通告,一目了然。
4.4 分析 TCP 窗口:你的接收端在喊停吗?
TCP 窗口大小,决定了发送端一次能扔多少数据出去。如果窗口太小,发送端就得等 ACK,吞吐自然上不去。
在 Wireshark 里,找到 TCP Window Size 字段。我一般关注两个值:
- 初始窗口——握手时协商的窗口大小
- 实时窗口——每个包里的窗口值,动态变化
如果实时窗口一路下跌,甚至变成 0,说明接收端处理不过来了。这就是典型的「接收端瓶颈」。
tcp.window_size。
举个例子。有一次我帮客户排查,iPerf 报告只有 200Mbps。打开抓包一看,窗口从 64KB 一路掉到 8KB,最后变成 0。接收端是台老服务器,网卡中断处理不过来。换了个多队列网卡,问题解决。
4.5 分析重传:网络真的可靠吗?
重传是吞吐的隐形杀手。一个重传包,不仅浪费带宽,还会触发拥塞控制,把发送窗口砍半。
在 Wireshark 里,重传包会标成黑色(默认配色)。你可以用 tcp.analysis.retransmission 过滤出来。
我一般看三个指标:
| 指标 | 正常范围 | 异常信号 |
|---|---|---|
| 重传率 | < 0.1% | > 1% 说明链路有问题 |
| 快速重传 | 偶尔出现 | 频繁出现说明丢包严重 |
| 超时重传 | 几乎为零 | 出现即代表 RTO 触发 |
快速重传和超时重传的区别在哪?快速重传是收到 3 个重复 ACK 后触发的,超时重传是等不到 ACK 超时了。后者更严重,因为发送端会停下来等。
我曾经遇到一个案例,重传率高达 5%。抓包一看,全是超时重传。最后发现是中间交换机的一个端口有 CRC 错误,导致包被静默丢弃。换了根网线,重传归零。
4.6 定位吞吐瓶颈:三步法
有了抓包数据,怎么快速找到瓶颈?我总结了三步:
- 看吞吐曲线——Wireshark 的 IO Graph 能画出每秒吞吐量。如果曲线波动大,说明不稳定。
- 看窗口变化——用
tcp.window_size画时间序列图。窗口持续下降,就是接收端瓶颈。 - 看重传分布——重传集中在某个时间段,说明那段时间链路有问题。
这三步走完,90% 的瓶颈都能定位。剩下的 10%,需要结合两端抓包做延迟分析。
4.7 实战案例:一个典型的吞吐瓶颈分析
说个真实的案例。某次测试,iPerf 报告吞吐 500Mbps,但业务方说实际只有 200Mbps。我抓了包,发现:
- 窗口大小始终在 64KB 左右,没变过
- RTT 稳定在 2ms
- 重传率 0.02%,正常
理论吞吐应该是 64KB / 2ms = 32MB/s ≈ 256Mbps。但 iPerf 报告 500Mbps,矛盾了。
仔细一看,iPerf 用了多线程(-P 4),每个线程独立窗口。4 个 64KB 窗口加起来就是 256KB,理论吞吐 1Gbps。但实际只有 500Mbps,说明瓶颈在别处。
再查 CPU 占用率——客户端 100%。原来是单核 CPU 撑不住了。换了个多核机器,吞吐直接飙到 900Mbps。
4.8 本章核心逻辑图
下面这张图总结了本章的分析流程:
4.9 避坑指南
最后,分享几个我踩过的坑:
- 别只抓一端——只抓客户端,你看不到服务端的窗口通告。两端对比才能定位问题。
- 别忽略时间戳——Wireshark 默认用相对时间。建议改成绝对时间(View → Time Display Format → Date and Time),方便和 iPerf 日志对齐。
- 别被「窗口缩放」骗了——TCP 握手时协商了 Window Scale 因子。Wireshark 会自动计算,但你要确认 Scale 值是否合理。Scale=7 意味着实际窗口是显示值的 128 倍。
我曾经犯过一个低级错误:抓包看到窗口是 64KB,以为没问题。后来才发现 Scale 因子是 0,实际窗口就是 64KB。而服务端支持 Scale=7,但客户端没开启。结果就是窗口被限制在 64KB,吞吐上不去。
嗯,细节决定成败。抓包分析就是这样——你越仔细,看到的就越多。