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。原因是什么?是两端的防火墙会话表不够大,双向流量一上来就开始丢包。你看,如果只测单向,这个问题根本发现不了。

注意: 同时双向测试对两端设备的 CPU 和内存压力更大。如果你用的是低端路由器或者嵌入式设备,-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。

小技巧: 并行流不是越多越好。流的数量超过 CPU 核心数后,反而会因为上下文切换导致性能下降。我一般建议:并行流数 ≤ 客户端 CPU 核心数 × 2。

另外,-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 高级技巧 双向测试 -r (轮流) -d (同时) 模拟全双工通信 并行流 -P 突破单流窗口限制 建议 ≤ CPU核心数×2 反向模式 -R 服务端→客户端 NAT/防火墙场景必备 JSON 输出 -J 自动化/监控集成 配合 jq 提取字段 带宽限制 -b 模拟弱网/限速 UDP 精确,TCP 近似 组合使用 -P 4 -R -J 灵活组合应对复杂场景

实战组合拳

最后,我分享一个我常用的“全链路压测”命令。这个命令能一次性拿到最全面的数据:

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 秒,避免冷启动阶段的数据干扰

嗯,这个命令跑完,基本上链路的真实性能就一览无余了。你想想看,如果连这种压力都扛得住,那日常业务流量基本不会有问题。

好了,这一章的内容就到这里。这些参数单独看都不难,但组合起来就是一门艺术。多在实际环境中试试,你会对网络有更深的理解。

一句话总结: 单条流测的是“能不能通”,并行双向测的才是“好不好用”。