4. iPerf3 高级技巧:双向测试、并行流、反向模式、JSON 输出、带宽限制
好,咱们继续往下聊。前面几章我们把 iPerf3 的基础用法和 TCP/UDP 测试都过了一遍。说实话,那些东西应付日常小规模排查是够了。但如果你真正去搞过大型网络割接、云间专线验收,或者帮客户定位过“为什么带宽跑不满”这种玄学问题,你就会发现——单条流的测试结果,很多时候就是个参考值,根本不能反映真实情况。
这一章,我带你看看 iPerf3 真正“高级”的地方。说白了,就是那些能让你在复杂场景下拿到真实数据的参数。我个人习惯把这几个参数称为“排障五件套”:-d、-r、-P、-R、-J、-b。一个一个来。
4.1 双向测试:-d 与 -r
先问一个问题:你测带宽的时候,是不是只测了从客户端到服务端的方向?
嗯,大多数人都这么干。但现实网络不是单行道。很多场景下,上行和下行的性能是完全不对称的。比如家用宽带,下行 500M,上行可能只有 30M。再比如某些云厂商的实例,出带宽和入带宽的限速策略也不一样。
所以,双向测试就很有必要了。
-r:先测一个方向,再测另一个方向
-r 参数的意思是“双向测试,但轮流来”。iPerf3 会先完成客户端到服务端的测试,然后自动交换角色,再测服务端到客户端。
# 服务端(不变)
iperf3 -s
# 客户端,开启双向轮流测试
iperf3 -c 192.168.1.100 -r
输出结果里你会看到两个测试结果,分别标注了方向。我个人觉得 -r 适合那种“我就想看看两个方向分别多少,不着急”的场景。因为它是串行的,总耗时是两次测试之和。
-d:同时双向测试
-d 就猛多了。它让客户端和服务端同时向对方发送数据。这才是真正模拟了真实网络中的全双工通信。
iperf3 -c 192.168.1.100 -d
我在项目中遇到过一个问题:某条专线,单向测能跑到 800Mbps,但业务一上线就卡得要死。后来用 -d 一测,双向同时跑的时候,总带宽直接掉到 300Mbps。原因是什么?是两端的防火墙会话表不够大,双向流量一上来就开始丢包。你看,如果只测单向,这个问题根本发现不了。
-d 的结果可能不准,因为瓶颈在设备本身,而不是链路。
4.2 并行流:-P
你有没有遇到过这种情况:iPerf3 默认单条流,怎么测都跑不满带宽?
嗯,这很正常。因为单条 TCP 流受限于“窗口大小”和“RTT(往返时延)”。你想想看,如果 RTT 是 100ms,窗口大小只有 64KB,那这条流的理论最大带宽也就 5Mbps 左右。哪怕你链路是万兆,也跑不上去。
这时候就需要并行流了。-P 参数可以让你同时开启多条流,把带宽“堆”上去。
# 开启 4 条并行流
iperf3 -c 192.168.1.100 -P 4
输出结果里,你会看到每条流的单独数据,最后还有一个 SUM 汇总行。我个人习惯在测试高带宽链路(比如 10Gbps 以上)时,先试 -P 4,不行再加到 -P 8 甚至 -P 16。
另外,-P 在 UDP 测试下也有效。但 UDP 的并行流更多是用来模拟多路并发场景,比如视频会议、VoIP 等。
4.3 反向模式:-R
这个参数其实很简单,但很实用。-R 表示“反向模式”。什么意思呢?就是让服务端主动向客户端发数据,而不是默认的客户端向服务端发。
iperf3 -c 192.168.1.100 -R
你可能会问:这和 -r 有什么区别?
区别大了。-r 是测完一个方向再测另一个,而 -R 是只测反向。而且 -R 有一个非常重要的应用场景:当客户端处于 NAT 后面,或者客户端防火墙限制了入站连接时。
我曾经帮一个客户排查问题,他的服务器在公网,客户端在内网。用默认方式测,结果只有 10Mbps。但客户说“我业务跑起来有 100Mbps 啊”。后来我让他用 -R 测,结果直接飙到 95Mbps。原因就是客户端的出站带宽没问题,但入站方向被公司防火墙限速了。你看,方向搞反了,结论就完全错了。
4.4 JSON 输出:-J
这个参数,说实话,是给“懒人”和“自动化脚本”准备的。
默认的 iPerf3 输出是人眼看的,但如果你想把它接入监控系统、写入数据库、或者用 Python 做后处理,那文本格式就太折磨人了。-J 参数让 iPerf3 输出标准的 JSON 格式。
iperf3 -c 192.168.1.100 -J
输出大概长这样(我简化了):
{
"start": {...},
"end": {
"sum_received": {
"bits_per_second": 952000000,
"retransmits": 3
},
"sum_sent": {
"bits_per_second": 948000000
}
}
}
我个人习惯在写自动化压测脚本时,用 -J 配合 jq 命令提取关键字段。比如:
iperf3 -c 192.168.1.100 -J | jq '.end.sum_received.bits_per_second'
这样就能直接拿到带宽数值,丢进 Grafana 或者 Zabbix 里做展示。
-J 输出,然后解析 JSON。结果发现如果测试过程中发生了错误(比如连接中断),JSON 输出会不完整,导致解析失败。所以建议在脚本里加个超时重试机制,或者先检查 JSON 是否合法。
4.5 带宽限制:-b
这个参数很有意思。它本来是给 UDP 测试用的,用来指定发送速率。但在新版 iPerf3(3.1 以上)中,它也可以用于 TCP 测试。
为什么要限制带宽?
嗯,场景很多。比如你想模拟一个 100Mbps 的链路环境,但实际网络是千兆的。或者你想看看在限速条件下,应用的延迟和丢包表现如何。
# UDP 测试,限制带宽为 50Mbps
iperf3 -c 192.168.1.100 -u -b 50M
# TCP 测试,限制带宽为 200Mbps(需要新版 iPerf3)
iperf3 -c 192.168.1.100 -b 200M
注意,TCP 下的 -b 其实是通过控制发送窗口来实现限速的,效果不如 UDP 那么精确。如果你需要精确的流量整形,建议还是用专业的流量控制工具(比如 tc),或者直接用 UDP 模式。
我记得有一次做视频会议系统的压力测试,客户要求模拟 2Mbps 的上行链路。我就用 -u -b 2M 配合固定包大小,完美复现了客户现场的环境。这个参数在模拟弱网环境时特别好用。
知识体系总览
好了,上面这些参数单独用都很简单,但组合起来就能玩出花。我画了一张图,帮你理清它们之间的关系和适用场景:
实战组合拳
最后,我分享一个我常用的“全链路压测”命令。这个命令能一次性拿到最全面的数据:
iperf3 -c 192.168.1.100 -P 8 -d -R -J -t 30
解释一下:
-P 8:8 条并行流,压满多核 CPU-d:同时双向测试,模拟全双工-R:反向模式也测一次(其实-d已经包含了双向,但-R可以单独看反向的 JSON 数据)-J:JSON 输出,方便后续分析-t 30:跑 30 秒,避免冷启动阶段的数据干扰
嗯,这个命令跑完,基本上链路的真实性能就一览无余了。你想想看,如果连这种压力都扛得住,那日常业务流量基本不会有问题。
好了,这一章的内容就到这里。这些参数单独看都不难,但组合起来就是一门艺术。多在实际环境中试试,你会对网络有更深的理解。