网络性能测试这件事,说简单也简单,说容易翻车也是真的容易翻车。很多人第一次接触 iperf3,是因为遇到一个很具体的场景:新装了一条千兆宽带,测速网站跑出来只有三百兆;或者两台服务器之间传文件慢得离谱,想确认到底是网线、网卡、交换机还是系统配置的问题。这时候 iperf3 就是最直接、最可信的答案——它不依赖浏览器、不依赖磁盘读写、不依赖第三方服务器,纯粹在两端之间打流量,把网络这条链路的能力单独拎出来量一遍。
这篇内容我会围绕 iperf3 的获取、部署、参数含义、TCP 与 UDP 两种打流方式、结果解读以及常见坑,完整讲一遍。适合刚接触网络测试的运维、后端、嵌入式、车载网络方向的从业者,也适合已经用过但一直没搞明白那些参数到底在干什么的人。我不会只给你一堆命令,而是把每个参数背后的意图讲清楚,这样你换一个场景也能自己推导出该用什么组合。
1. 先把 iperf3 装到两端:获取渠道与部署方式
1.1 为什么优先用系统包管理器而不是随便找个安装包
iperf3 的获取方式其实很多,但我的建议非常明确:能用系统包管理器就用包管理器。原因有三个。第一,包管理器装出来的版本和系统库是匹配的,不会出现动态链接库缺失的问题;第二,升级和卸载干净;第三,也是最容易被忽略的一点——很多第三方站点提供的所谓"绿色版"安装包,版本号看着很新,实际编译选项可能阉割了某些功能,比如多线程或者某些拥塞控制算法支持。
在常见的 Linux 发行版上,安装就是一行命令的事:
# Debian / Ubuntu 系 sudo apt update sudo apt install -y iperf3 # RHEL / CentOS / Rocky / Alma 系 sudo yum install -y iperf3 # 或者新版用 dnf sudo dnf install -y iperf3 # openSUSE sudo zypper install -y iperf3装完先确认版本,这一步别省:
iperf3 --version版本信息里会带上编译时的特性,比如是否支持--version之外的某些扩展。我一般会记下两端的版本号,尽量保证两端版本一致或者接近。iperf3 的协议在不同大版本之间有过调整,跨版本测试偶尔会出现握手异常或者结果对不上的情况,尤其是 3.0 和 3.1 之间那段历史。
1.2 Windows 与 macOS 上的获取思路
Windows 上没有官方的一键安装程序,主流做法是下载官方发布的编译好的二进制压缩包,解压后把目录加到 PATH 里,或者直接在解压目录里开命令行运行。这里要提醒一句:下载来源尽量认准官方项目发布页,不要从各种聚合下载站拿,那些站点的包经常被重新打包,甚至夹带东西。
macOS 上最省事的是 Homebrew:
brew install iperf3如果你在 macOS 上遇到权限或者网络接口相关的问题,先确认是不是系统防火墙拦了监听端口,这个后面排错章节会细讲。
1.3 部署时最容易忽略的两件事
第一件是防火墙。iperf3 服务端默认监听 5201 端口,很多系统默认策略是拒绝入站的。测试之前先在服务端确认端口可达,否则你会花半小时怀疑网卡,结果只是防火墙没放行。
# 临时放行(firewalld) sudo firewall-cmd --add-port=5201/tcp --add-port=5201/udp # 永久放行 sudo firewall-cmd --permanent --add-port=5201/tcp --add-port=5201/udp sudo firewall-cmd --reload第二件是两端时钟和网卡状态。测试前用ethtool看一眼协商速率,如果网卡协商成了百兆,你后面怎么测都上不去千兆,这不是 iperf3 的问题,是链路本身的问题。
ethtool eth0 | grep -i speed提示:如果两端之间隔着多台交换机或者做了链路聚合,先确认聚合模式。有些聚合模式单条流跑不满总带宽,需要多流并发才能压满,这一点在后面的多流测试里会展开。
2. 服务端与客户端:一次标准测试的完整动作拆解
2.1 服务端到底在做什么
很多人把服务端当成一个"等着被连"的黑盒,其实理解它在干什么,对排错帮助极大。iperf3 服务端启动后,会在指定端口上监听,等待客户端发起控制连接。控制连接建立后,双方协商测试参数,然后真正跑数据的是另外的数据连接。默认情况下,服务端是接收方(sink),客户端是发送方(source)。
启动服务端最基础的命令:
iperf3 -s这条命令会监听默认的 5201 端口。如果你想指定端口,加-p:
iperf3 -s -p 6001如果想让服务端跑完一次测试就退出(适合脚本化调用),加-1或者--one-off:
iperf3 -s -1这个-1参数在自动化场景里非常有用。比如你写一个批量测试脚本,每台机器轮流当服务端,跑完就退出,不会残留进程占着端口。
2.2 客户端发起测试的最小命令
客户端最基本的用法就是指定服务端地址:
iperf3 -c 192.168.1.100默认行为是:TCP 协议、持续 10 秒、单条流、客户端发送。跑完你会看到一段结果,包含传输量、带宽、重传次数等。这里先记住一个结论:默认测试是 TCP 上行(客户端到服务端)。很多人第一次测完发现结果和预期不符,就是因为没意识到方向问题。
如果要测反方向,也就是服务端发给客户端,加-R:
iperf3 -c 192.168.1.100 -R-R是 reverse 的意思,它会翻转数据流向。这个参数在实际工作中用得极多,因为很多链路的上行和下行能力并不对称,尤其是无线和某些专线场景。
2.3 测试时长与报告间隔的取舍
默认 10 秒对快速验证够用,但要观察稳定性就不够了。我一般会把时长拉到 30 秒甚至 60 秒:
iperf3 -c 192.168.1.100 -t 60同时加上-i控制报告间隔,默认是 1 秒一次,如果测试时间很长,输出会刷屏,可以改成 5 秒:
iperf3 -c 192.168.1.100 -t 60 -i 5这里有个经验:观察抖动和丢包,间隔不要太长。1 秒间隔能让你看到瞬时的波动,5 秒间隔会把波动平均掉,看起来更"漂亮"但掩盖了问题。做稳定性评估时,我倾向用 1 秒间隔,哪怕输出长一点。
2.4 并行流:单条流跑不满时该怎么办
这是新手最容易困惑的地方。明明链路是万兆,单条 TCP 流只跑出两三个 G,是不是有问题?不一定。单条 TCP 流的吞吐受限于拥塞窗口、往返时延、接收窗口这几个因素的共同作用。在有一定时延的链路上,单流很难压满高带宽,这是 TCP 的固有特性,不是故障。
解决办法就是开并行流:
iperf3 -c 192.168.1.100 -P 8-P 8表示开 8 条并行流。多流并发能绕过单流的窗口限制,把链路总带宽压出来。我通常的做法是:先用单流测一遍,再用 4 流、8 流各测一遍,对比结果。如果多流能接近链路理论带宽,说明链路本身没问题,单流上不去是协议特性;如果多流也上不去,那才需要往链路、网卡、系统参数方向查。
3. 参数详解:那些你一直没搞明白的选项
3.1 协议选择与 UDP 打流的正确姿势
TCP 测试测的是"在可靠传输下能跑多快",而 UDP 测试测的是"在指定速率下丢多少包"。这两个问题的答案完全不同,用途也不同。
UDP 测试必须指定目标带宽,因为 UDP 没有拥塞控制,你不告诉它发多快,它不知道该发多少:
iperf3 -c 192.168.1.100 -u -b 100M-u切到 UDP,-b 100M表示目标带宽 100 Mbps。注意这里的单位,M是兆比特每秒,不是兆字节。如果你写成-b 100m,小写 m 在某些版本里含义不同,建议统一用大写。
UDP 测试的核心看点是丢包率和抖动。结果里会有一行 jitter(抖动)和 lost/total(丢包)。如果丢包率超过 1%,在实时音视频场景里就已经很难受了;超过 5% 基本不可用。
做 UDP 打流时有个细节:带宽要逐步往上加。比如先 100M,再 200M,再 500M,观察从哪个点开始丢包。这个"开始丢包的临界点"往往就是链路或者设备的真实处理上限,比直接怼一个高带宽然后看一堆丢包有用得多。
3.2 窗口大小与 MSS:影响单流吞吐的关键旋钮
TCP 窗口大小直接决定单流能跑多快。理论上的上限可以用这个公式估算:
吞吐上限 ≈ 窗口大小 / 往返时延(RTT)举个例子,如果 RTT 是 20ms,窗口是 64KB,那么单流上限大约是 64KB / 0.02s = 3.2MB/s,换算成比特大约是 25.6 Mbps。这就是为什么跨地域链路上单流经常跑不快——不是带宽不够,是窗口和时延的乘积限制了。
iperf3 里可以用-w指定窗口大小:
iperf3 -c 192.168.1.100 -w 256KMSS(最大报文段长度)用-M指定:
iperf3 -c 192.168.1.100 -M 1400注意:
-w和-M不是越大越好。窗口过大在某些设备上会触发缓冲区问题,MSS 设置不当会导致分片。测试时建议先保持默认,确认基线后再针对性调整。
3.3 常用参数速查表
| 参数 | 含义 | 典型用法 |
|---|---|---|
-s | 服务端模式 | iperf3 -s |
-c | 客户端模式,后接地址 | iperf3 -c 10.0.0.1 |
-p | 指定端口 | -p 6001 |
-u | 使用 UDP | -u -b 100M |
-b | 目标带宽(UDP 必填) | -b 500M |
-t | 测试时长(秒) | -t 60 |
-i | 报告间隔(秒) | -i 1 |
-P | 并行流数量 | -P 8 |
-R | 反向测试 | -R |
-w | TCP 窗口大小 | -w 256K |
-M | MSS 大小 | -M 1400 |
-4/-6 | 强制 IPv4 / IPv6 | -4 |
-J | 输出 JSON 格式 | -J |
-l | 读写缓冲区长度 | -l 128K |
-1 | 服务端跑完一次退出 | iperf3 -s -1 |
这张表建议存下来,实际用的时候对着查比翻文档快。
3.4 JSON 输出:让结果能被程序处理
手工看结果是一回事,做批量测试和自动化报告是另一回事。-J参数会把结果输出成 JSON:
iperf3 -c 192.168.1.100 -J > result.json拿到 JSON 之后,你可以用脚本提取end.sum_received.bits_per_second这类字段,汇总成表格。我在做多机房链路巡检时就是这么干的:一个脚本遍历所有目标,逐个跑 iperf3,把 JSON 结果收集起来生成对比报表。这比人工一条条看效率高太多。
4. 结果解读:数字背后的真实含义
4.1 带宽数字怎么读才不误导自己
结果里最显眼的是 Bitrate,比如9.41 Gbits/sec。但你要注意这个数字是接收端统计的还是发送端统计的,两者可能不一致。发送端统计的是"我发出去了多少",接收端统计的是"我实际收到多少"。如果两者差距大,说明中间有丢包或者拥塞。
TCP 测试里,如果发送端显示 9.4G,接收端显示 8.9G,中间那 0.5G 去哪了?大概率是重传消耗掉了。这时候要去看 Retr(重传)那一列。
4.2 重传次数:TCP 测试里最该盯的指标
重传次数是判断链路质量的关键。理想情况下,局域网内 TCP 测试重传应该是 0 或者个位数。如果重传成百上千,说明链路有丢包,TCP 在不停地补。
[ ID] Interval Transfer Bitrate Retr [ 5] 0.00-10.00 sec 1.09 GBytes 938 Mbits/sec 0 sender上面这个例子重传是 0,链路很干净。如果重传数字很大,先别急着怀疑网卡,按这个顺序查:网线质量、交换机端口错误计数、两端网卡错误计数。
# 查看网卡错误和丢包统计 ip -s link show eth0 # 或者 netstat -i4.3 UDP 结果里的抖动和丢包怎么判断
UDP 测试结果长这样:
[ ID] Interval Transfer Bitrate Total Datagrams [ 5] 0.00-10.00 sec 119 MBytes 100 Mbits/sec 86200 [ 5] 0.00-10.00 sec 119 MBytes 100 Mbits/sec 86200 receiver接收端那一行会额外带上 jitter 和 lost:
[ 5] 0.00-10.00 sec 118 MBytes 99.0 Mbits/sec 0.052 ms 12/86200 (0.014%)这里的0.052 ms是抖动,12/86200 (0.014%)是丢包。抖动在 1ms 以内算优秀,1-5ms 可接受,超过 10ms 在实时通信里就要警惕了。丢包率 0.014% 属于正常范围,超过 1% 就要查原因。
4.4 一个容易被忽略的细节:CPU 占用
高速测试时,iperf3 本身会吃 CPU。如果你在测万兆甚至更高带宽,单核可能成为瓶颈。这时候你会看到带宽上不去,但链路其实是好的。判断方法很简单:测试时用top看 iperf3 进程的 CPU 占用,如果某个核跑满了,那就是 CPU 限制。
解决办法是开多流(-P),让多个核分担负载。这也是为什么高带宽测试几乎都要用多流的原因之一。
5. 踩坑实录:那些让我浪费过时间的场景
5.1 服务端没起来,客户端一直卡住
最常见的现象是客户端执行后长时间无输出,最后超时。原因通常是服务端没启动、端口不对、或者防火墙拦了。排查顺序:
- 服务端确认进程在:
ps aux | grep iperf3 - 服务端确认端口在监听:
ss -tlnp | grep 5201 - 从客户端测端口连通性:
nc -zv 192.168.1.100 5201 - 检查防火墙规则
这四步走完,基本能定位到问题在哪一层。
5.2 结果忽高忽低,重复性差
有时候同一对机器,跑三次结果差很多。这种情况先排除背景流量。测试期间如果有其他大流量在跑,结果必然不稳。其次是网卡节能特性,某些网卡的节能模式会导致性能波动,可以在测试期间临时关闭:
sudo ethtool -s eth0 wol d还有就是中断亲和性,高带宽场景下网卡中断如果都落在同一个核上,会成为瓶颈。这个属于进阶调优,普通测试可以先不管。
5.3 UDP 测试报 "unable to set UDP buffer size"
这个报错通常出现在 UDP 高带宽测试时,原因是系统默认的 UDP 缓冲区不够大。解决办法是调大系统参数:
# 临时调整 sudo sysctl -w net.core.rmem_max=26214400 sudo sysctl -w net.core.wmem_max=26214400iperf3 本身也可以用-l调整读写缓冲区长度来缓解。这个坑我在做高带宽 UDP 打流时踩过,当时以为是网卡问题,查了半天才发现是缓冲区限制。
5.4 两端版本不一致导致的诡异现象
前面提过版本问题,这里展开说一个具体表现:某些版本组合下,反向测试-R的结果会明显异常,或者 JSON 输出字段缺失。遇到这种"看起来不像网络问题"的异常,先核对两端版本,统一版本后重测,能省下大量排查时间。
6. 把 iperf3 用进日常工作流
6.1 链路验收的标准动作
新链路交付或者机房搬迁后,我一般会跑一套标准测试:TCP 单流、TCP 8 流、TCP 反向、UDP 逐步加压。四个动作下来,链路的上行、下行、并发能力、丢包特性就都清楚了。这套动作可以写成一个脚本,输入两端地址就自动跑完并生成报告。
6.2 长期监控里的轻量用法
iperf3 也可以做周期性探测。用-t 5短时测试配合定时任务,把结果写进日志,长期看趋势。带宽突然下降或者重传突然增多,往往能提前发现链路劣化。这种用法对时长和带宽要求都不高,重点是持续和可对比。
6.3 和其他工具的分工
iperf3 测的是纯网络层能力,它不关心应用协议。如果你要测 HTTP 吞吐,那是另一类工具的事;要测磁盘 IO,也不是 iperf3 的范畴。搞清楚它的边界,才不会拿它去回答它回答不了的问题。我见过有人用 iperf3 测出来的结果去解释应用慢,这中间还隔着协议栈、应用逻辑、数据库等好几层,不能直接划等号。
实际用下来,iperf3 最大的价值在于它足够"纯粹"——它把网络这条链路单独隔离出来量一遍,给你一个干净的基线。有了这个基线,再去排查上层问题,心里就有底了。至于那些参数,用多了自然就熟了,关键是理解每个参数在解决什么问题,而不是死记命令。