☰
iPerf3 网络性能测试实战:带宽、UDP抖动与自动化压测
2026/10/14 7:00:31 网站建设 项目流程

1. 入坑 iPerf3:这台工具到底解决什么问题

做网络运维、音视频传输、云服务器性能评估的人,手上几乎都备着一个 iPerf3。它是我见过最“专一”的网络性能测试工具,没有花哨的界面,也没有复杂的安装依赖,就是一个命令行程序,却能回答一个最基础但最关键的问题:两台机器之间,实际能跑多少带宽?

别小看这个问题。很多时候业务方反馈“系统卡顿”“视频延迟高”“文件同步很慢”,第一反应是查服务器负载、查数据库慢查询,但我往往先做一件事:用 iPerf3 把网络这条链路单独拉出来打一炮,看它到底是不是瓶颈。因为应用层的性能再优化,如果底层链路只能跑 30Mbps,那应用能表现的极限也就是 30Mbps,并不会因为代码写得漂亮就能超越物理链路。

iPerf3 可以用来测量 TCP 和 UDP 的最大带宽,还能报告抖动(Jitter)和数据包丢失率。它采用经典的 C/S 架构,一端跑服务端,一端跑客户端,中间建立一个测试连接,然后尽力塞数据,最终告诉你这条链路的极限在哪里。它解决的核心痛点有三个:

  • 链路到底能跑多少:不要猜,直接压;
  • 网络质量稳不稳:通过 UDP 模式的抖动和丢包率看客观指标;
  • 性能瓶颈在哪一端:配合多线程、窗口大小等参数,快速区分是单流瓶颈还是整体链路瓶颈。

适合谁来学?如果你是刚接触网络测试的新人,这篇文章可以带你完整掌握 iPerf3 的工具逻辑;如果你已经用过几次,但只会敲iperf3 -c和iperf3 -s两个命令,那本文后面关于 JSON 输出、自动化脚本、瓶颈排查和调优的部分,应该能帮你把工具用到“骨子里”。

2. 先把环境跑起来:安装、启动与第一个测速

2.1 两端安装与最基本的使用姿势

iPerf3 的安装非常简单。Linux 上各发行版都有现成包:

# Debian / Ubuntu / Deepin apt install -y iperf3 # CentOS / RHEL / Rocky Linux yum install -y epel-release yum install -y iperf3 # Arch Linux pacman -S iperf3

macOS 用户如果有 Homebrew,直接brew install iperf3。Windows 上就更简单,从官网下载编译好的 exe 文件,放到任意目录即可,客户端和服务端是一样的二进制。我一直觉得 Windows 版本的 iperf3 是最方便的压测工具,因为它不需要任何安装,双击命令行就能跑,而且还能放在 U 盘里带着走。

安装完之后,在 Server 端启动服务:

iperf3 -s

默认监听 5201 端口。接着在 Client 端发起测试:

iperf3 -c 192.168.1.10

如果一切正常,10 秒钟后你会看到一段测试报告。第一次跑通这个命令的时候,你可能会觉得“就这么简单?”是的,就这么简单。但 iPerf3 的价值恰恰体现在,当你想深入评估一条链路时,它对参数的表达能力极其丰富。

2.2 第一个测试结果怎么读

默认测试 10 秒,客户端每 1 秒打印一条结果。下面是一段比较典型的输出:

Connecting to host 192.168.1.10, port 5201 [ 5] local 192.168.1.20 port 52340 connected to 192.168.1.10 port 5201 [ ID] Interval Transfer Bitrate [ 5] 0.00-1.00 sec 11.2 MBytes 93.8 Mbits/sec [ 5] 1.00-2.00 sec 11.3 MBytes 94.7 Mbits/sec [ 5] 2.00-3.00 sec 11.4 MBytes 95.4 Mbits/sec ... [ 5] 9.00-10.00 sec 11.2 MBytes 94.2 Mbits/sec - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bitrate [ 5] 0.00-10.00 sec 112 MBytes 94.1 Mbits/sec

关键信息有三个:Transfer 表示这段时间内实际传输的数据量,Bitrate 是吞吐带宽,最后的汇总行是整个测试期间的平均值。你需要关注的是汇总行的 Bitrate,而不是每一秒的瞬时值。

看到这里,很多新手会陷入一个误区:以为是客户端从服务端下载带宽。实际上,iPerf3 默认情况下是客户端往服务端发数据,也就是测试“客户端的上行带宽”。如果你想测客户端从服务端下载的表现,要加-R参数实现反向模式。

注意:iPerf3 客户端参数中的-R让数据流从 Server 端发向 Client 端,此时测试方向是 Server 到 Client,可以理解为“下行带宽”。

2.3 记住这几个高频参数就够了

iPerf3 参数很多,但日常评估链路,真正高频用到的其实就下面这些:

参数作用典型用法
-c <host>指定客户端连接的服务端地址iperf3 -c 192.168.1.10
-s以服务端模式启动iperf3 -s
-p <port>指定端口,默认 5201iperf3 -c 192.168.1.10 -p 5202
-t <sec>测试时长,默认 10 秒iperf3 -c 192.168.1.10 -t 30
-i <sec>每隔几秒打印一次结果iperf3 -c 192.168.1.10 -i 1
-P <n>并行线程数,即同时开几条数据流iperf3 -c 192.168.1.10 -P 4
-R反向模式,测下行带宽iperf3 -c 192.168.1.10 -R
-u使用 UDP 协议测试iperf3 -c 192.168.1.10 -u -b 100M
-b <bandwidth>UDP 模式目标带宽iperf3 -c 192.168.1.10 -u -b 500M
-w <size>设置 TCP 窗口大小iperf3 -c 192.168.1.10 -w 4M
-O <sec>忽略测试开始前 N 秒的数据iperf3 -c 192.168.1.10 -O 3
-J以 JSON 格式输出结果iperf3 -c 192.168.1.10 -J
--logfile <file>结果写入文件iperf3 -c 192.168.1.10 --logfile /tmp/result.txt
--get-server-output在客户端同时拿到服务端的统计结果iperf3 -c 192.168.1.10 --get-server-output

这些参数不是每个都需要马上记住,看到这里你可以先复刻一遍基本用法,后面遇到具体问题再回去查表。

3. 三条核心测试链路:上行、下行与多线程并发

3.1 默认单流测试,到底测的是什么

iPerf3 默认是单条 TCP 流,从客户端发向服务端,时长 10 秒。单流测出来的带宽,反映的是“单个 TCP 连接在最理想情况下能跑多少”,这个数字通常受几个因素制约:TCP 窗口大小、往返时延(RTT)、报文的拥塞控制算法、单核 CPU 的处理能力。

举个例子,你在同一个局域网内测两台机器,RTT 只有 0.5ms 左右,TCP 窗口不用开多大就能跑满千兆网卡。但如果两台机器跨城市、RTT 有 30ms,那情况就完全不一样了。TCP 的吞吐量理论上受限于带宽时延积(BDP),计算公式是:

BDP = 带宽(bps) × RTT(秒)

如果带宽是 1000Mbps、RTT 是 0.03 秒,那 BDP 就是 30Mbit,约 3.75MB。也就是说,TCP 窗口至少要能容纳 3.75MB 的数据在链路上“排队”,才能把 1000Mbps 的带宽打满。默认的 socket 缓冲往往没这么大,单流成绩自然上不去。这就是为什么跨地域链路用单流测试时,经常出现“明明买的是 500M 专线,iPerf3 却只能跑 150M”的现象。

所以单流测试的最大价值,是揭示链路在默认协议栈配置下的真实传输表现。它不代表链路不行,只代表默认配置下的能力边界。

3.2 想测双向带宽?iPerf3 的设计你得先懂

iPerf3 和旧版 iPerf2 有一个明显区别:iPerf2 可以同时双向收发数据,而 iPerf3 默认是单向的。你要测双向,需要手动跑两次,或者用两个服务端实例来“夹击”。

常用的做法是:先跑一次上行,再跑一次下行:

# 测客户端 → 服务端方向 iperf3 -c 192.168.1.10 -t 30 # 测服务端 → 客户端方向 iperf3 -c 192.168.1.10 -t 30 -R

这样分开测的优点在于,两个方向的结果互不干扰,能清晰看到链路是否对称。专线不对称的现象其实挺常见,比如上行 200M、下行 400M,如果业务对两个方向都有较高要求,这种不对称就很关键。

如果业务场景确实需要“同时双向”,我习惯在 Server 端多开几个实例,每个实例占用不同端口,然后用两个客户端同时打流。

# Server 端开两个实例 iperf3 -s -p 5201 iperf3 -s -p 5202 # Client A 打 5201 方向,Client B 打 5202 方向 iperf3 -c 192.168.1.10 -p 5201 -t 30 iperf3 -c 192.168.1.10 -p 5202 -t 30 -R

这种方案虽然不算严格意义上的“同一进程双向测试”,但在真实项目中完全够用,而且能模拟双向流量对链路完整性造成的影响。

3.3 多线程参数 -P:什么时候该加,加多少合适

-P 4的意思是同时建立 4 条 TCP 连接,并行发数据。这是解决“单流跑不满”问题的最直接手段。因为单流受限于 TCP 窗口和单核 CPU,多流可以把负载分摊到多个 CPU 核心上,也能让链路上同时存在多个 TCP 流,合起来的总带宽自然更高。

那多线程怎么选数值?我的经验是分两步走。

第一步,先跑单流,记录基线数字。第二步,从 4 开始试,逐步翻倍:-P 4、-P 8、-P 16,观察汇总 Bandwidth 是否继续上升。如果加到 8 之后没有明显提升,说明瓶颈已经不在连接数量上,而是到了链路带宽上限或服务端 CPU 上限。继续加没有意义,只会增加 CPU 开销和结果抖动。

我做过一次跨机房测试,单流只能跑 300Mbps,-P 4跑到了 850Mbps,-P 8稳定在 920Mbps,-P 16反而掉到 880Mbps。为什么?并发连接过多以后,CPU 软中断和上下文切换开销超过了多流带来的收益。所以不是越大越好,测到持平甚至下降的拐点,就是当前环境下的最优并发数。

多线程还有一个隐性好处:它能发现网卡多队列(RSS)是否工作正常。如果-P 8之后依然非常低,可以顺手查一下网卡中断是否全部集中在 CPU0 上。

4. UDP 测试:带宽、抖动与丢包率才是网络质量的照妖镜

4.1 UDP 模式的基本参数和行为

TCP 模式测的是“尽力而为的可靠传输极限”,但很多实时业务(语音、视频、游戏同步)用的是 UDP,对延迟和抖动更敏感。iPerf3 的 UDP 模式就是为这个场景设计的。

UDP 测试的命令:

iperf3 -c 192.168.1.10 -u -b 500M -t 30 -i 1

这里有个非常关键的参数-b。UDP 模式不会像 TCP 一样自动适应带宽,默认只按 1Mbps 的速率发包。你如果不加-b,那测出来的结果基本没有参考价值。-b 500M是告诉客户端“按 500Mbps 的目标速率往对端发 UDP 包”。

UDP 模式本身没有拥塞控制,发送端会尽可能按设定速率丢包到网络上,因此测试期间整条链路上就是实打实的 UDP 流量。目标速率设太高,链路扛不住,就会产生丢包;设太低,链路不饱和,丢包率接近 0,结论又不可信。所以一般建议把-b设置在预估带宽的 80%~120% 之间,分档位测试。

4.2 结果中的 Jitter 和 Lost 怎么理解

UDP 测试结束,结果和 TCP 模式最大的区别在于多了一行抖动和丢包统计:

[ ID] Interval Transfer Bandwidth Jitter Lost/Total Datagrams [ 5] 0.00-10.00 sec 57.3 MBytes 48.1 Mbits/sec 0.105 ms 0/40986 (0%) [ 5] Sent 40986 datagrams

Jitter 单位是毫秒,反映网络上数据包到达时间间隔的波动幅度。波动越大,说明网络排队或拥塞越明显,语音、视频就会出现卡顿或杂音。一般局域网环境下 Jitter 应该低于 1ms,跨机房或长途链路上,个位数毫秒都算正常,如果超过 10ms 甚至几十毫秒,那就要留意了。

Lost/Total Datagrams 是丢包统计,0/40986 表示总共发送 40986 个包,丢了 0 个。这个指标非常直接:丢包率越高,链路质量越差。如果要快速判断链路是否稳定,我可以只看这一行。

拿专线验收来举例,假设你租了一条宣称 100Mbps 的专线,用 UDP 分别打 80M、100M、120M:

目标速率实际带宽丢包率结论
80M79.8M0%链路余量充足
100M99.2M0.2%接近达标,小部分拥塞
120M108M9.5%超过链路承载上限

这个测试能非常直观地告诉你:链路容量的天花板在哪里,运营商承诺的带宽有没有水分。

4.3 UDP 测试能暴露出哪些 TCP 看不到的问题

TCP 有重传机制,丢包之后会自动降速重发,所以 TCP 成绩往往看不出链路上的瞬时抖动,只会表现为带宽下降。而 UDP 测试是“有多少发多少”,丢包和抖动数据直接暴露链路的真实承压能力。

我举一个实际场景:某业务跨机房同步数据,TCP 测试结果始终保持在 900Mbps 左右,看起来链路挺好。但 UDP 打到 500Mbps 时,丢包率达到 3%,Jitter 也偏高。后来排查确认,是中间某台交换机在突发流量下出现了队列丢弃。这说明链路在持续大流量下并不稳定,TCP 因为自身有滑动窗口机制,掩盖了这个问题。UDP 测试直接把问题揪出来了。

所以测试规范里,我习惯这样定位:先用 TCP 测带宽上限,再用 UDP 测链路质量。两个都跑一遍,才能对链路形成完整的认知。

注意:UDP 测试一定要控制目标速率和时间,不要随随便便拿一个超大的带宽值去打生产链路。我见过有人直接用-b 10000M打一条千兆链路,那瞬间产生的丢包压力会让业务侧明显感知到卡顿,甚至触发防火墙的限速策略。

5. 把 iPerf3 接进自动化脚本:JSON 输出和批量压测

5.1 为什么要从纯文本换成 JSON 输出

默认的文本报告用来人工瞄一眼还行,但一旦你有几十组测试要做、或者需要存档对比历史数据,纯文本解析起来非常痛苦。iPerf3 提供了-J参数,所有结果一次性以 JSON 格式输出,结构清晰,易于程序解析。

iperf3 -c 192.168.1.10 -J --logfile /tmp/iperf_result.json

JSON 里包含客户端发送的汇总数据、每秒快照、TCP 或 UDP 详情,甚至如果加了--get-server-output,还能把服务端的统计结果一并带回来。这是我从手动测试走向半自动化测试的关键一步。

JSON 输出里最常关注的字段是:

  • end.sum_sent.bits_per_second:总发送速率
  • end.sum_received.bits_per_second:总接收速率
  • end.sum_sent.seconds:测试时长
  • end.streams:每个流的明细,多线程测试时需要看这个
  • 如果跑的是 UDP,end.sum.udp.lost_packets和end.sum.udp.jitter_ms是核心指标

5.2 写一个简单的批量压测脚本

实际项目中,我很少只跑一条命令就下结论,而是会写一个批量脚本,按固定的参数矩阵去测试多个方向、多个并发数。下面是一个简化的 bash 脚本,核心逻辑是从一个列表里循环执行测试,并把关键结果提取成一行摘要。

#!/bin/bash SERVER="192.168.1.10" PORT=5201 RESULT_FILE="/tmp/iperf_summary.csv" echo "direction,threads,bandwidth_mbps,retrans" > ${RESULT_FILE} # 上行测试:默认方向 for threads in 1 4 8; do iperf3 -c ${SERVER} -p ${PORT} -t 15 -P ${threads} -J \ --logfile /tmp/iperf_tcp_up_${threads}.json bandwidth=$(jq -r '.end.sum_sent.bits_per_second' /tmp/iperf_tcp_up_${threads}.json) retrans=$(jq -r '.end.sum_sent.retransmits' /tmp/iperf_tcp_up_${threads}.json) bandwidth_mbps=$(awk "BEGIN {printf \"%.1f\", ${bandwidth} / 1000000}") echo "up,${threads},${bandwidth_mbps},${retrans}" >> ${RESULT_FILE} done # 下行测试:反向模式 for threads in 1 4 8; do iperf3 -c ${SERVER} -p ${PORT} -t 15 -R -P ${threads} -J \ --logfile /tmp/iperf_tcp_down_${threads}.json bandwidth=$(jq -r '.end.sum_received.bits_per_second' /tmp/iperf_tcp_down_${threads}.json) retrans=$(jq -r '.end.sum_received.retransmits' /tmp/iperf_tcp_down_${threads}.json) bandwidth_mbps=$(awk "BEGIN {printf \"%.1f\", ${bandwidth} / 1000000}") echo "down,${threads},${bandwidth_mbps},${retrans}" >> ${RESULT_FILE} done cat ${RESULT_FILE}

脚本里我用jq解析 JSON 字段。如果你的环境里没有 jq,可以用 Python 替代,也很好用:

import json import subprocess def run_iperf(server, port=5201, duration=15, threads=1, reverse=False): cmd = [ "iperf3", "-c", server, "-p", str(port), "-t", str(duration), "-P", str(threads), "-J" ] if reverse: cmd.append("-R") ret = subprocess.run(cmd, capture_output=True, text=True) data = json.loads(ret.stdout) if reverse: bps = data["end"]["sum_received"]["bits_per_second"] else: bps = data["end"]["sum_sent"]["bits_per_second"] retrans = data["end"]["sum_sent"]["retransmits"] return bps / 1_000_000, retrans print(run_iperf("192.168.1.10", threads=4)) # (带宽Mbps, 重传次数)

5.3 把服务端数据也拉回来:--get-server-output

iPerf3 有个隐藏优势:服务端和客户端看到的统计结果可能不一样,尤其在丢包或不对称链路下。客户端默认只打印自己的视角,但加一个--get-server-output参数后,客户端可以把服务端的统计结果也拉回来一并显示。

iperf3 -c 192.168.1.10 -J --get-server-output --logfile /tmp/result_with_server.json

然后在 JSON 里,服务端数据会出现在server_output字段中。结合两端数据对比,可以判断问题是出现在方向 A→B 还是 B→A,这对网络排障非常有用。比如:

  • 客户端显示发送 100M,服务端显示只收到 90M,说明中间丢了 10M 的流量;
  • 服务端显示的接收带宽远低于客户端发送,就要怀疑中间链路或服务端协议栈丢弃。

这种两端对比能力,在普通 ping 和文件传输测试里很难得到,也是我强烈推荐把 iPerf3 纳入自动化巡检的原因。

6. 常见报错与性能瓶颈排查实录

6.1 连接类报错对照表

在使用过程中,最常见的其实不是“测出来慢”,而是“压根连不上”。下面这张表是我把这几年遇过的连接类问题做了归纳:

报错信息原因解决办法
unable to connect to server服务端没启动,或 IP/端口不对确认服务端iperf3 -s是否在跑,检查端口是否一致
connect failed: Connection refused端口未监听,或被防火墙拦截netstat -tlnp看端口,放行 5201
bind failed: Address already in use端口被占用,或上一次测试的服务端未正常退出换端口-p 5202,或杀掉残留 iperf3 进程
Permission denied使用了小于 1024 的端口,或系统限制换高端口,检查 SELinux / 系统策略
No route to host网络路由不通,或中间防火墙挡掉了ping、traceroute分段排查
control socket error: Connection reset by peer对端 iperf3 版本不兼容,或连接被重置确认两端 iperf3 版本一致
server is already running服务端实例重复启动先杀掉旧进程再启动

版本一致性值得单独强调一下。iPerf3 客户端和服务端的协议是绑定到特定版本的,不同大版本之间经常无法互通。我建议两端安装同一版本,最简单的办法是在 Server 端执行iperf3 -v,然后让客户端保持同样的版本号。

6.2 带宽上不去的五个真实原因

“能连上但速率太低”才是排障的重头戏。按我遇到过的频率排序,原因基本集中在以下五类:

第一,TCP 窗口太小。这是跨地域测试中最常见的问题。解决办法是用-w手动指定窗口大小,比如:

iperf3 -c 192.168.1.10 -w 8M -t 30

窗口大小设置的最大值还受系统net.core.wmem_max限制,如果你设了 8M 没生效,要去sysctl里调整。理想窗口约等于带宽乘以 RTT,比如 RTT 20ms、目标 500Mbps,窗口大约 1.25MB。

第二,网卡协商速率不是预期值。看似千兆网卡,实际协商成了百兆,速率上限就是 100Mbps。先跑一下:

ethtool eth0

看 Speed、Duplex、Auto-negotiation。这应该成为测速第一步,不要跳过去。

第三,CPU 单核成为瓶颈。单流测试时,TCP 的处理往往压在一个 CPU 核心上,如果网卡不支持多队列,或者中断没有分散,单核跑满是常有的事。这时候用-P 4甚至-P 8多线程测试,通常能得到有效提升。

第四,网卡 offload 功能异常。某些虚拟化环境或者老驱动下,TSO/GRO 开着反而会导致带宽异常衰减。可以用ethtool -k eth0查看特性,ethtool -K eth0 tso off临时关闭后再测一次对照。

第五,中间链路质量差或限速。这种情况最隐蔽。两端的网卡都是千兆,本地互 ping 正常,但到对端就是跑不满。可以通过 UDP 模式测试丢包和抖动,如果丢包高,基本就是中间链路或运营商问题。

6.3 测试工具自身的坑也要避一避

有一类问题不是网络造成的,而是 iPerf3 自身特性造成的,容易让人误判。最常见的是 TCP 慢启动效应。TCP 连接建立初期,带宽会从低慢慢往上爬,如果测试时长只有 10 秒,开头几秒的“爬坡”数据会拉低平均值,特别是跨地域高 RTT 链路,前 3 秒可能只跑了一半速率。

解决办法是用-O参数忽略开头的若干秒:

iperf3 -c 192.168.1.10 -t 30 -O 5

意思是总时长 30 秒,但前 5 秒数据不记入统计。这个参数在远程链路测试时几乎是必加的。

另一个坑是-P多线程的时候,默认报告里每一条流都会单独打印。如果流数多,输出会刷屏,反而看不清汇总。加-i 1可以限制打印间隔,或者干脆用-J只拿最终 JSON 数据。

提示:压测前务必确认目标机器和链路的承载能力,不要在业务高峰期直接打满带宽。我在某次白天压测时就把一条共享出口带宽打满,结果整个办公室业务侧都卡了,从那以后做生产链路压测前,一定会先发变更通知,并选择业务低峰期执行。

7. 进阶调优:让测试数字更接近真实链路极限

7.1 用 BDP 公式计算出理想的 TCP 窗口

当你做完单流测试后,如果发现带宽只有预期的六成甚至一半,很可能就是窗口没调好。用 BDP 公式可以算出理论窗口:

窗口大小 = 带宽 × RTT

假设带宽 1000Mbps,RTT 30ms,换算成字节:

1000Mbps = 125MB/s 125MB/s × 0.03s = 3.75MB

也就是说,TCP 接收缓冲至少要 3.75MB,才能让窗口不被填满。实际测试时我会开一个略大于理论值的窗口,比如-w 4M,再往大调,直到带宽不再增长。注意:-w参数同时影响两端,服务端和客户端都使用这个值才有效。

如果设置了窗口但测出来还是没变化,去检查系统的最大缓冲限制:

sysctl net.core.wmem_max sysctl net.core.rmem_max

如果是默认的 208KB,那你在命令行里设 4M 会被强制压低到上限值。临时提高:

sysctl -w net.core.wmem_max=8388608 sysctl -w net.core.rmem_max=8388608

7.2 多线程之外的 CPU 绑定和网卡队列

多线程-P解决了 CPU 单核瓶颈,但还不够精细。如果想在压测时让性能和表现更稳定,可以给 iPerf3 进程绑定 CPU 核心,避免操作系统把进程在不同核之间来回调度。

# 固定 iPerf3 进程绑定到 CPU2 和 CPU3 taskset -c 2,3 iperf3 -c 192.168.1.10 -P 2 -t 30

同时检查网卡是否开起了多队列,以及中断是否分布到不同 CPU:

# 查看网卡队列数量和中断分布 ethtool -l eth0 cat /proc/interrupts

如果网卡支持多队列但只有一个队列在工作,可以尝试ethtool -L eth0 combined 4把队列数调成和 CPU 核数一致或匹配。这一步对高吞吐场景提升非常明显,尤其是在新买的物理服务器上,“网卡没调队列”是很多人忽略的点。

7.3 协议栈层面的调优选项

TCP 拥塞控制算法在高延迟长链路场景里,对吞吐的影响非常大。Linux 上常见的算法有 cubic、bbr、reno 等。查看当前所用的算法:

sysctl net.ipv4.tcp_congestion_control

如果当前是 cubic,在长肥链路上可以考虑测试 bbr,只要内核支持就能直接换:

sysctl -w net.ipv4.tcp_congestion_control=bbr

换算法前先跑一次 iPerf3 记录基线,换完之后再跑一次,对比数据再决定是否长期使用。这个动作建议做成可回滚的变更,不要直接在核心服务器上永久修改。

不过要特别提醒一点:调优是“最后一公里”,不要本末倒置。先把网卡协商、防火墙策略、中间链路质量这些基础项排查完,再碰协议栈。

8. 一个完整实战案例:跨机房专线验收需要用到的命令组合

8.1 测试前准备清单

假设你要验收一条跨机房的专线,两端的 IP 分别是 A(服务端)和 B(客户端),带宽承诺 500Mbps。我会按下面的清单做准备工作:

  1. 两端确认 iPerf3 版本一致:iperf3 -v;
  2. 服务端放行 TCP 5201 和 UDP 5201 端口;
  3. 两端关闭或确认不影响测试的防火墙规则;
  4. 用ping确认基础连通性,同时记录 RTT;
  5. 用ethtool确认两端网卡协商速率满足测试预期;
  6. 协调业务方,确认当前链路没有大流量并发任务。

这六条看起来琐碎,但每一条踩过坑的人都懂。比如防火墙漏放 UDP 端口,你跑 TCP 一切正常,UDP 测试直接超时;版本不一致,客户端连上去结果直接报协议错误。准备清单相当于给自己兜底。

8.2 测试命令序列与预期结果记录

测试过程中,我建议用下面这套命令组合,每一条都对应一个明确的评估维度:

# 1. 单流上行,看默认协议栈下的基础带宽 iperf3 -c A_SERVER_IP -t 30 -O 5 -i 1 # 2. 四流上行,看链路总体吞吐 iperf3 -c A_SERVER_IP -t 30 -O 5 -P 4 # 3. 单流下行 iperf3 -c A_SERVER_IP -t 30 -O 5 -R # 4. 四流下行 iperf3 -c A_SERVER_IP -t 30 -O 5 -R -P 4 # 5. UDP 100M,验证链路在低负载下的质量 iperf3 -c A_SERVER_IP -u -b 100M -t 30 # 6. UDP 500M,验证链路在承诺带宽下的质量 iperf3 -c A_SERVER_IP -u -b 500M -t 30 # 7. UDP 600M,验证链路是否有余量 iperf3 -c A_SERVER_IP -u -b 600M -t 30

如果测试结果如下:

测试项速率丢包/重传结论
单流上行180Mbps重传较多默认窗口不足或 RTT 偏高
四流上行501Mbps正常链路总容量满足承诺带宽
单流下行176Mbps重传较多与上行类似,单流受限
四流下行495Mbps正常下行总容量达标
UDP 100M99Mbps0%低负载质量良好
UDP 500M498Mbps0.1%承诺带宽下质量稳定
UDP 600M560Mbps7.8%超出容量,丢包明显

从这个结果可以得出清晰的结论:链路总容量达到了承诺的 500Mbps,但单流表现较差,瓶颈大概率是 TCP 窗口或中间设备的单流限速策略,而不是链路本身。后续如果要承载单线程大文件传输,需要重点优化同侧协议栈参数。

8.3 从结果反推问题,形成验收报告

验收报告里,我最喜欢用一张表把测试类型、原始数据、结论放在一起,然后给出建议。要注意的是,不要只给“达标/不达标”结论,还要指出影响达标的具体因素。比如上面单流只有 180M,如果报告只写“不达标”而不分析原因,运营商大概率会拿“多流能跑满”来反驳你,让你陷入扯皮。

好的报告逻辑应该是这样的:

  1. 先给结论:链路总容量达标;
  2. 再给细节:单流受限,建议排查 QoS 策略或调优服务器参数;
  3. 附上原始命令和 JSON 输出作为证据。

这样无论是内部存档还是对外沟通,都经得起推敲。JSON 输出的价值在此时体现得最充分,把所有原始文件按日期存档,以后链路性能劣化时,直接调出来对比,很快就能看出是运营商侧劣化了还是自己调整过配置。

我在实际项目中还发现一个很实用的小技巧:给每一轮测试打上时间戳命名,比如iperf_up_4thr_20250108.json,这样几个月后回看,自己也能快速定位当时的测试环境,而不用打开 JSON 再看字段里的时间。

这个内容后续还可以这样扩展:把 iPerf3 集成到定时巡检脚本里,每天早上自动跑一轮 TCP 加 UDP 测试,发现某条链路带宽比前一日下降超过 20%,就往告警系统推一条消息。网络质量劣化往往不是瞬间的,而是慢慢衰减的,定时测速相当于给链路装了一块仪表盘。你要做的其实就是把前面那段 Python 脚本套进 cron 或 systemd timer 里,剩下的交给时间去验证。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询