一、前言
在深夜的机房中,两台服务器之间闪烁的网卡指示灯,似在默默低语。运维人员老张紧盯着监控大屏上起伏的带宽曲线,眉头拧成了个疙瘩。新部署的分布式存储系统在跨机房同步时,传输速率始终未能达到预期。他掏出手机,给同事发了条信息:“用iperf3测一下AB两区的带宽质量,我怀疑中间链路过载了。”
这,便是网络性能测试工作中的一个常见场景。无论是对IDC机房间专线质量的验证,还是在家庭宽带升级后检验实际速率,又或是评估企业VPN隧道的稳定性,iperf3这个看似简单的命令行工具,总能在关键时刻,成为工程师们手中精准的“听诊器”。它不像图形化工具那般繁杂,而是凭借最纯粹的TCP/UDP流量冲击,直抵网络传输的核心矛盾。在复杂的网络环境里,理论带宽与实际性能之间,往往横亘着协议栈优化、硬件瓶颈、路由策略等诸多难题。本文将引领你拨开这些重重迷雾,从基础安装开始,逐步深入到高阶调优,全面掌握这个网络诊断利器的各类用法。
二、安装iperf3
2.1 Linux系统中安装iperf3
在Linux的各大发行版中,软件源大多自带iperf3,通常可直接从软件源进行安装。若需安装特定版本的iperf3,则可考虑采用编译安装的方式。
2.1.1 从软件源安装
不同发行版对应的安装命令如下:
发行版 | 安装命令 |
---|---|
Centos/Redhat | yum install iperf3 -y |
Archlinux | pacman -Sy iperf3 |
Debian/Ubuntu/Kali | apt install iperf3 -y |
Gentoo | emerge --ask net-misc/iperf |
2.1.2 编译安装
iperf3的项目地址为:https://github.com/esnet/iperf/releases 。截至当前,其最新版本为3.18,这里以安装3.18版本为例进行说明。
cd /opt/
wget https://github.com/esnet/iperf/releases/download/3.18/iperf-3.18.tar.gz
tar xf iperf-3.18.tar.gz
cd iperf-3.18
./configure && make && make install
安装完成后,可通过执行“iperf3 -v”命令来查看输出信息:
若安装过程失败,可尝试先运行“./bootstrap.sh”脚本,之后再进行安装操作。
2.2 Windows系统下安装iperf3
在Windows系统中安装iperf3,你可前往 此页面 或 github发布页面 下载相应版本的iperf3二进制文件。下载时,务必依据系统架构选择匹配的版本,即32位或64位版本 。完成下载后,将文件解压至指定路径,随后把该路径添加到系统环境变量PATH中,如此便能在系统的任意位置便捷地调用iperf3。
倘若不想配置环境变量,仅作临时使用,通过cmd命令行工具打开文件解压路径,同样能够直接执行iperf3相关操作。
三、实战场景测试:从基础实践到复杂环境实证
3.1 单线程压测及元数据说明
3.1.1 单线程压测
在进行网络性能测试时,最简单的压测方式便是采用单线程模式,即不加任何额外参数,此时iperf3会默认以单线程运行。以下是本次测试所涉及的客户端和服务端的相关信息:
IP | 操作系统 | 网卡规格 | |
---|---|---|---|
客户端A | 192.168.1.14 | Kali Linux | 2.5Gbps |
服务端B | 192.168.1.8 | Gentoo Linux | 2.5Gbps |
在服务端,执行以下命令进行监听,若不指定端口,iperf3会默认监听5201端口:
iperf3 -s
客户端则通过执行以下命令发起压测,其中<server_ip>
需替换为服务端的实际IP地址:
iperf3 -c <server_ip>
压测结果中各字段的含义如下:
字段 | 说明 |
---|---|
Interval | 代表测试时间区间,用于明确在该时间段内进行数据传输的相关统计。 |
Transfer | 记录数据传输量,包含sender(发送方)发送的数据量以及receiver(接收方)接收的数据量。 |
Bitrate | 表示带宽,单位为bit,同样分为sender发送带宽与receiver接收带宽,用于衡量数据传输的速率。 |
Retr | 即重传次数,反映了在数据传输过程中,由于各种原因导致数据包需要重新发送的次数。 |
Cwnd | 指拥塞窗口,它的作用是限制发送方在未收到接收方确认(ACK)之前,最多能够发送的数据量,以此来控制网络拥塞情况。 |
3.1.2 元数据交互解析(Wireshark抓包实战)
借助Wireshark抓包工具,能够清晰地观察到iperf3在测试过程中发起了两个TCP连接。在正式传输压测数据之前,第一个TCP连接承担着至关重要的任务,它主要以json格式传输一系列参数,用于控制测试过程。客户端与服务器通过这个连接交换关键的测试配置信息,其中涵盖了测试时长、数据包大小、并行流数量等重要参数 :
以图中红圈标注的参数为例,其具体含义如下:
字段 | 含义 |
---|---|
“len”:131072 | 明确指定了数据包的长度为131072字节,该长度会影响数据传输的效率和网络负载。 |
“parallel”:1 | 表明本次测试使用的线程数为1,即采用单条数据流进行传输,而非并行传输模式。 |
“pacing_time”:“1000” | 表示数据发送的间隔为1000毫秒,此参数对于控制数据发送节奏、避免网络拥塞具有重要意义。 |
“client_version”:“3.18” | 显示客户端所使用的iperf3版本为3.18,不同版本可能在功能和性能上存在差异。 |
此外,在这个连接传输的信息中,还包含了客户端和服务器的资源使用情况,例如CPU利用率:
字段 | 含义 |
---|---|
“cpu_util_total”:10.89 | 表示系统的总CPU利用率为10.89%,反映了整个系统在测试过程中的CPU资源占用情况。 |
“cpu_util_user”:0.156 | 指用户态CPU利用率为0.156%,体现了用户进程在CPU资源使用上的占比。 |
“cpu_util_system”:10.733 | 代表内核态CPU利用率为10.733%,展示了内核在管理系统资源和处理网络请求等操作时对CPU资源的消耗。 |
而到了第二个TCP连接,才真正开始传输压测数据。从TCP会话界面可以看到,第一个TCP会话主要用于元数据的交换,因此传输的数据量较少;第二个TCP会话则传输了3GB的数据。其中,客户端(A)向服务端(B)压测时的带宽速率为2332Mbps。从网络带宽占用的角度来看,这个传输方向对于客户端A而言,主要占用的是出带宽;对于服务端B来说,主要占用的则是入带宽:
3.2 协议开销计算
在前面的测试中,我们使用的是2.5G网卡规格,然而实际压测得到的速率仅为2.36G,这是为什么呢?原因在于协议本身存在开销。在不考虑物理层开销的情况下,TCP与IP头部的开销总计为40字节。
3.2.1 TCP/IP头部开销公式
基础开销
- TCP头部开销(默认):
\(H_{\text{TCP}} = 20 \text{Bytes}\)
- IPv4头部开销(默认):
\(H_{\text{IPv4}} = 20 \text{Bytes}\)
- 总网络层开销:
\(H_{\text{Network}} = H_{\text{TCP}} + H_{\text{IPv4}} = 40 \text{Bytes}\)
- MTU为1500字节时,TCP/IP协议开销占比:
\(\text{开销占比} = \frac{\text{IP头} + \text{TCP头}}{\text{数据包总长度}} \times 100\% = \frac{\textcolor{orange}{20} + \textcolor{orange}{20}}{\textcolor{orange}{1500}} \times 100\% \approx \textcolor{orange}{2.67\%} \)
需要注意的是,以上计算尚未将以太网的开销纳入其中(14字节以太网帧 + FCS 4字节 = 18字节),所以实际开销可能会超过2.67%。
3.2.2 有效带宽计算
理论最大带宽:
\([ \text{有效带宽} = 2.5 \text{Gbps} \times \frac{1460}{1500} \approx 2.43 \text{Gbps} ]\)
巨型帧优化(MTU = 9000 Bytes):
倘若采用巨帧,在一定程度上能够降低开销,具体计算如下:
\([ \text{有效带宽} = 2.5 \times \frac{9000 - 40}{9000} = 2.5 \times \frac{8960}{9000} \approx 2.48 \text{Gbps} ]\)
3.3 多线程并行测试:突破单流限制(-P)
iperf3在默认状态下执行单线程压测,而借助 -P 选项,我们能够指定多线程进行测试(iperf2版本并不支持多线程参数)。这一功能主要用于突破单线程的瓶颈,模拟高并发的网络场景。
IP | 操作系统 | 网卡规格 | |
---|---|---|---|
客户端A | 192.168.1.14 | Kali Linux | 2.5Gbps |
服务端B | 192.168.1.8 | Gentoo Linux | 2.5Gbps |
在服务端,执行以下命令开启监听:
iperf3 -s
客户端发起压测的命令为:
iperf3 -c <server_ip> -P 8
这里的 -P 8 表示指定使用8个线程进行压测。
从结果中可以看到,iperf3启动了8个线程,并且在SUM字段会统计总的带宽值。
通过Wireshark抓包,在第一条TCP流中,能够清晰地看到客户端所使用的参数:
在整个测试过程中,共产生9个TCP会话。其中,第一个会话如前文所述,是iperf3进行元数据交换的阶段,并不包含在这8个线程之中:
其他多线程示例
- 使用10个线程进行压测,持续时间为60秒:
iperf3 -c <server_ip> -P 10 -t 60
- 启动10个并行线程,跳过前2秒的TCP慢启动阶段,并且每秒输出一次测试状态:
iperf3 -c <server_ip> -P 10 -O 2 -i 1
3.4 UDP暴力测试:真实带宽压榨术 (-u)
为什么要进行UDP压测呢?这是因为TCP会利用 滑动窗口 以及 拥塞控制算法(诸如慢启动、拥塞避免、快速重传等机制)来动态调整数据的发送速率。当网络出现丢包或者延迟现象时,TCP会主动降低发送速率,以此避免网络拥塞。这种“智能”特性使得TCP压测的结果往往低于网络实际带宽上限,无法充分挖掘网络资源的潜力。
与之不同的是,UDP不存在流量控制和拥塞控制机制,发送端能够持续以 最大速率 发送数据包,直至将网络带宽占满。这种“暴力”特性让UDP在探测网络的物理带宽极限方面更具优势。
IP | 操作系统 | 网卡规格 | |
---|---|---|---|
客户端A | 192.168.1.14 | Kali Linux | 2.5Gbps |
服务端B | 192.168.1.12 | ArchLinux | 2.5Gbps |
在服务端,执行如下命令进行监听:
iperf3 -s
客户端发起压测时需要注意,必须加上 -b 参数。因为如果不指定压测带宽,出于保护机制,iperf3默认只会以大约1Mbps的带宽进行压测。若要不限制压测带宽,可使用 -b 0 表示。具体命令如下:
iperf3 -c <server_ip> -u -b 0
从客户端的抓包结果可以看出,即便在进行UDP压测,元数据的交换依旧采用的是TCP协议:
而在后续的UDP压测阶段,数据传输为单方向,不需要服务端回包:
需要提醒的是,不限制带宽的压测可能会导致网络带宽被完全占用,如果此时有其他业务正在运行,极有可能影响业务通信。若要针对具体带宽进行压测,在 -b 参数后直接接上带宽值即可,例如 -b 200M、 -b 2.5G、 -b 10G 等。对于UDP压测,iperf3还提供了 –dont-fragment 参数,用于设置UDP包不分片,不过需要注意的是,TCP并不支持此参数 。
3.5 反向测试(-R):解决端口暴露难题 (-R/–reverse)
在网络性能测试场景中,当A作为iperf3客户端,B作为服务端,若需要压测B的出带宽以及A的入带宽时,反向压测功能便派上用场,此时无需将A和B的角色进行互换。
这种场景常见于以下两种情况:
- 例如A本身没有公网IP,若要通过公网链路压测B,A若想进行外网端口监听,就需要进行DNAT映射或者使用网络穿透技术,这不仅操作繁琐,而且在许多场景下并非必要。
- A所处的网络环境存在安全策略等限制,不便于放开任何对外监听端口,仅允许主动发起网络请求,而不允许被其他设备主动访问。
基于上述种种情况,当A作为客户端,B作为服务端,想要压测B的出带宽以及A的入带宽时,只需使用反向压测参数 -R 即可。此时,服务端B将向客户端A发送数据 。
IP | 操作系统 | 网卡规格 | |
---|---|---|---|
客户端A | 192.168.1.14 | Kali Linux | 2.5Gbps |
服务端B | 192.168.1.8 | Gentoo Linux | 2.5Gbps |
在服务端,执行以下命令开启监听:
iperf3 -s
客户端发起反向压测的命令为:
iperf3 -c <server_ip> -P 10 -R # -P 10 使用十个线程压测
通过Wireshark的会话分析(Wireshark conversation),能够清晰地看到数据是从B向A的方向传输:
3.6 双向测试(–bidir):全链路容量评估
当需要同时对A、B两端的出入带宽进行压测时,可以使用双向压测参数 –bidir。
IP | 操作系统 | 网卡规格 | |
---|---|---|---|
客户端A | 192.168.1.14 | Kali Linux | 2.5Gbps |
服务端B | 192.168.1.8 | Gentoo Linux | 2.5Gbps |
在服务端,执行如下命令开启监听:
iperf3 -s
客户端发起双向压测的命令为:
iperf3 -c <server_ip> -P 5 --bidir
为了便于直观展示输出结果,这里仅使用了5个线程进行压测,实际应用中可根据业务需求灵活选择线程数量。从结果中可以看到,客户端和服务端均有两个方向的带宽速率统计:TX-C表示从客户端发送出去的带宽(Transmit-Client),RX-C表示从客户端接收到的带宽(Receive-Client),RX-S表示服务端接收带宽(Receive-Server),TX-S表示服务端发送出去的带宽(Transmit-Server)。
通过Wireshark的会话页面可以观察到,A到B和B到A的链路基本都被占满:
进一步仔细观察会发现,虽然是两个方向同时进行压测,但无一例外都是由客户端主动连接服务端。即便指定了5个线程,在双向压测模式下,iperf3实际上开启了10个线程,其中5个线程用于正向传输,另外5个线程用于反向传输:
那么,为什么在过滤SYN数据包时会显示有11个连接呢?这是因为第一个TCP连接是iperf3客户端和服务端之间用于交互元数据的连接,此时还未真正开始压测数据,这一步骤主要是为后续的压测做准备工作,详细内容可参考上文的 3.1.2 章节 。
3.7 高延迟环境下的带宽塌缩与调优
TCP的传输效率在很大程度上依赖于滑动窗口(Window Size)机制。窗口大小决定了发送方在等待接收方确认(ACK)之前能够发送的最大数据量。网络时延越高,数据包从发送方到达接收方并返回ACK的时间就越长。如果窗口大小无法满足带宽时延积( BDP, Bandwidth-Delay Product)的要求,发送方就会因为等待ACK而暂停数据发送,进而导致网络带宽无法得到充分利用。
3.7.1 带宽时延积(BDP)
BDP的计算公式为:
\(BDP = B_{\text{(bps)}} \times RTT_{\text{(s)}} \)
该公式表示网络中“正在传输中”的数据总量。例如,当带宽为1Gbps(即1,000,000,000 bps)、时延为50ms(即0.05秒)时:
\(BDP = 10^9 \times 0.05 = 5 \times 10^7\ \text{bits} \approx 6.25\ \text{MB} \)
若TCP窗口大小小于BDP,实际网络带宽将会受到限制。而iperf3默认的窗口大小可能无法适配高时延链路的需求 。
3.7.2 模拟高延时对带宽压测的影响
在开展模拟实验之前,务必确保清除已有的流量控制(tc)规则,具体操作命令如下:
sudo tc qdisc del dev eth0 root 2>/dev/null # eth0 需替换为实际的网卡名称
完成规则清除后,我们先在iperf3单线程模式下,测试无限制条件下的网络带宽。本次测试涉及的客户端A与服务端B的相关信息如下:
IP | 操作系统 | 网卡规格 | A到B的RTT | 协议 | |
---|---|---|---|---|---|
客户端A | 192.168.1.14 | Kali Linux | 2.5Gbps | 约1ms | TCP |
服务端B | 192.168.1.8 | Gentoo Linux | 2.5Gbps | 约1ms | TCP |
在服务端,执行以下命令开启监听:
iperf3 -s
客户端发起压测的命令为:
iperf3 -c <server_ip>
从测试结果可知,在默认情况下,压测带宽约为2.36G。
接下来,运用控制变量法,将A到B的网络延时增加至约100ms(即0.1秒),具体操作命令如下:
sudo tc qdisc add dev eth0 root netem delay 99ms # eth0 需替换为实际的网卡名称,由于B到A之间链路本身已有1ms的RTT,在此基础上增加99ms即可
此时,客户端A与服务端B的相关信息变更为:
IP | 操作系统 | 网卡规格 | A到B的RTT | 协议 | |
---|---|---|---|---|---|
客户端A | 192.168.1.14 | Kali Linux | 2.5Gbps | 约100ms | TCP |
服务端B | 192.168.1.8 | Gentoo Linux | 2.5Gbps | 约100ms | TCP |
再次使用相同的iperf3单线程压测命令进行测试,结果如下:
可以明显看出,带宽急剧下降至约230Mbps。
3.7.3 如何优化提升压测带宽
承接上文的问题,为何带宽会降至约230Mbps?我们先来查看客户端和服务端的窗口大小情况。
查看客户端的发送窗口大小(CWND),执行命令:
sysctl net.ipv4.tcp_wmem
查看服务端的接收窗口大小(RWND),执行命令:
sysctl net.ipv4.tcp_rmem
无论是 tcp_rmen 还是 tcp_wmen,输出的三个字段分别代表最小值(min)、默认值(default)、最大值(max)。实际有效的窗口大小为:
\(\text{有效窗口} = \min(\mathrm{CWND},\ \mathrm{RWND}) = \min(4\ \mathrm{MB},\ 6\ \mathrm{MB}) = 4\ \mathrm{MB} = \underbrace{4{,}194{,}304\ \mathrm{Bytes}}_{=33{,}554{,}432\ \mathrm{bits}} \)
同时,已知客户端到服务端的RTT延时为100ms。基于这些信息,我们来计算理论带宽大小:
\[ \begin{aligned} \text{带宽 (Mbps)} &= \frac{\text{有效窗口大小 (bits)}}{\text{RTT (秒)}} \\ &= \frac{33{,}554{,}432\ \mathrm{bits}}{0.1\ \mathrm{s}} \\ &\approx 335.5\ \mathrm{Mbps} \end{aligned} \]
依据上述公式,我们能够推导出单线程情况下,TCP连接在 理论 上所能达到的带宽大小。然而,实际带宽还受到诸多其他因素的影响,其中包括但不限于:
- 网络拥塞或丢包:即便网络带宽充裕,丢包现象也会触发数据包重传机制,进而降低网络的有效吞吐量。
- 硬件性能瓶颈:网卡、CPU或者磁盘I/O的性能限制,可能导致其无法处理高吞吐量的数据传输。
- 客户端和服务端的发送缓冲区、接收缓冲区是否已经达到上限。
- 协议开销:TCP/IP头部以及MTU分片等操作会占用部分网络带宽,其中TCP/IP头部(40字节)约占用3%的带宽。
通过对上述这些公式未涵盖的其他因素进行调整优化,能够使压测带宽尽可能接近理论带宽值。此外,采用多线程压测、增大窗口大小、降低网络延时等方式,也能够直接提升网络带宽的利用率。
例如,增大窗口大小。增大客户端发送窗口大小的操作命令如下:
sysctl -w net.ipv4.tcp_wmem="4096 16384 33554432" # 发送窗口最大值设为32MB
增大服务器端接收窗口大小的命令为:
sysctl -w net.ipv4.tcp_rmem="4096 131072 33554432" # 接收窗口最大值设为32MB
增大接收缓冲区和发送缓冲区大小的命令分别为:
sysctl -w net.core.rmem_max=33554432 # 32MB
sysctl -w net.core.wmem_max=33554432 # 32MB
需注意的是,以上操作仅为临时增大相关参数值。若要使这些设置永久生效,需要编辑/etc/sysctl.conf文件,修改其中相关的内核调优参数,然后执行sysctl -p命令使设置永久生效。
倘若通过iperf3指定的窗口大小 小于 缓冲区大小,将会出现以下错误提示:
同时,缓冲区大小也不宜盲目增大,过大的max值可能会导致系统内存耗尽(OOM)。
完成上述设置后,客户端通过增大窗口进行压测,执行命令:
iperf3 -c <server_ip> -w 32M #窗口大小指定为32MB
从测试结果可以清晰地看到,压测带宽有了显著提升。
3.7.4 使用UDP压测规避上述影响
运用UDP进行压测,能够巧妙地绕开TCP所具备的流量控制、拥塞控制以及窗口大小限制等一系列会对带宽产生影响的因素,从而挖掘出最为真实的网络带宽瓶颈。不过需要注意的是,如果在UDP压测时不限制压测带宽的大小,极有可能导致机器性能被过度消耗,若此时通过ssh连接这台机器,ssh连接甚至可能会被意外中断。鉴于此,这里我们指定以2.25G带宽进行压测。本次测试的客户端A与服务端B相关信息如下:
IP | 操作系统 | 网卡规格 | A到B的RTT | 协议 | |
---|---|---|---|---|---|
客户端A | 192.168.1.14 | Kali Linux | 2.5Gbps | 约100ms | UDP |
服务端B | 192.168.1.12 | ArchLinux | 2.5Gbps | 约100ms | UDP |
客户端发起压测的命令为:
iperf3 -c <server_ip> -u -b 2.25G
从测试结果可以清晰地看到,2.25G的出带宽已被全部占满,即便到服务端的延时约为100ms,UDP压测也能达到这样的效果。
3.8 高丢包网络的生存指南
在开展模拟实验之前,务必确保已将流量控制(tc)的相关策略全部清空,具体操作命令如下:
sudo tc qdisc del dev eth0 root 2>/dev/null # eth0 需替换为实际的网卡名称
随后,在客户端设置20%的丢包率,执行命令如下:
sudo tc qdisc add dev eth0 root netem loss 20% # eth0 需替换为实际的网卡名称
3.8.1 模拟丢包对TCP带宽压测的影响
在进行实际压测之前,我们可通过相关公式来对20%丢包率情况下理论上能够压测到的带宽进行估算。已知如下条件:
MSS大小 | RTT | RTO | 丢包率(p) | 拥塞算法 |
---|---|---|---|---|
1460 | 1ms | 1ms × 2 | 20% | CUBIC |
TCP的吞吐量会受到RTT和丢包率(p)的显著影响,并且系统默认的拥塞控制算法为CUBIC,此时我们可采用常用的 Padhye 公式来进行估算:
\( \text{Throughput} = \frac{\text{MSS}}{ RTT \cdot \sqrt{ \frac{2bp}{3} } + RTO \cdot \min\left( 1,\, 3\sqrt{ \frac{3bp}{8} } \right) \cdot p(1 + 32p^2) } \)
将上述数据代入公式进行计算:
\[ \begin{aligned} \text{Throughput} &= \frac{1460 \, \text{B}}{1 \, \text{ms} \cdot \sqrt{\frac{2 \cdot 1 \cdot 0.2}{3}} + 2 \, \text{ms} \cdot \min\left(1,\, 3\sqrt{\frac{3 \cdot 1 \cdot 0.2}{8}}\right) \cdot 0.2 \cdot (1 + 32 \cdot 0.2^2)} \\ &= \frac{1460}{\sqrt{0.1333} + 0.7494} = \frac{1460}{1.1144} \, \frac{\text{B}}{\text{ms}} \\ &= 1310 \, \frac{\text{B}}{\text{ms}} \times 8 \, \frac{\text{bits}}{\text{B}} \times 10^3 \, \frac{\text{ms}}{\text{s}} = \boxed{10.48 \, \text{Mbps}} \end{aligned} \]
这里计算得出的10.48Mbps仅仅是依据公式理论估算出来的数值。接下来进行实际压测,本次压测的客户端A与服务端B相关信息如下:
IP | 操作系统 | 网卡规格 | A到B的RTT | 协议 | 丢包率 | |
---|---|---|---|---|---|---|
客户端A | 192.168.1.14 | Kali Linux | 2.5Gbps | 约1ms | TCP | 20% |
服务端B | 192.168.1.8 | Gentoo Linux | 2.5Gbps | 约1ms | TCP | 0% |
在服务端,执行以下命令开启监听:
iperf3 -s
客户端发起压测的命令为:
iperf3 -c <server_ip> -P 10 # 使用10个线程并行
从实际压测结果可以看出,与理论估算值基本相符。在丢包率极高的网络场景中,由于频繁触发超时重传机制以及拥塞窗口(CWND)重置,导致TCP长时间处于慢启动阶段,进而使得有效吞吐量进一步降低。
面对这种情况,我们可以考虑启用BBR拥塞控制算法。首先查看当前系统所使用的默认算法,执行命令:
cat /proc/sys/net/ipv4/tcp_congestion_control
临时启用BBR算法的命令如下:
sudo sysctl -w net.ipv4.tcp_congestion_control=bbr
完成上述设置后,再次进行压测,从结果可以看到,速率有了较为显著的提升:
在20%丢包率的情况下,Cubic/Reno拥塞控制算法可能致使CWND无法有效增长,吞吐量近乎为零。因此,选用BBR算法相对而言具有更强的抗丢包能力。除了调整拥塞算法之外,还可考虑增大接收缓冲区和发送缓冲区大小、采用多线程压测等优化手段 。
3.8.2 模拟丢包对UDP带宽压测的影响
同样是基于20%的丢包率开展模拟测试,相关信息如下:
IP | 操作系统 | 网卡规格 | A到B的RTT | 协议 | 丢包率 | |
---|---|---|---|---|---|---|
客户端A | 192.168.1.12 | ArchLinux | 2.5Gbps | 约1ms | UDP | 20% |
服务端B | 192.168.1.8 | Gentoo Linux | 2.5Gbps | 约1ms | UDP | 0% |
为避免网卡因负载过高而导致断连,在客户端压测时指定带宽为2.3G,使用UDP进行压测,命令如下:
iperf3 -c <server_ip> -u -b 2.3G
在A对B进行压测的过程中,对于客户端A而言,压测的是出带宽。由于UDP是无状态的,不存在拥塞控制算法,它并不关注数据是否成功发送出去,所以即便丢包率达到20%,依然能够压测出2.3G的带宽。而对于服务端B来说,客户端A发送给它的压测数据有20%丢失,因此其入口只能接收到80%的数据包,计算可得:2.3G × 0.8 = 1.84Gbps,这与上图所示结果相符。
所以,若链路上存在丢包情况,不会影响发送端压测的出带宽,但会对接收端的入带宽产生影响。粗略估算时,接收端入带宽 = 压测带宽 ×(1 - 丢包率) 。
3.9 一些通用参数
在iperf3使用过程中,有一些相对高频使用的通用类参数,如下所示:
参数 | 说明 |
---|---|
-p,–port | 用于指定服务端监听端口 |
-i,–interval | 可指定压测间隔 |
-t,–time | 用来设置压测时间 |
–cport | 能够设置客户端端口 |
-O,–omit | 可跳过TCP慢启动阶段 |
3.9.1 指定服务端监听端口(-p,–port)
当服务端进行监听时,如果不指定端口,默认使用5201/tcp端口。通过 -p 参数能够指定其他端口,例如:
iperf3 -s -p 55000 # 指定端口为55000
当服务端指定了自定义端口后,客户端也需要通过 -p 参数指定与之对应的端口,命令如下:
iperf3 -c <server_ip> -p 55000
此参数适用于默认端口被占用,或者安全策略仅允许特定端口或端口范围通行的场景。
3.9.2 指定压测间隔及压测时间(-i|-t)
这两个参数仅适用于客户端,服务端无法使用。客户端默认的压测时间间隔为1秒,默认压测时长为10秒。通过 -i 参数能够指定时间间隔,例如:
iperf3 -c <server_ip> -i 0.1 # 间隔0.1秒压测一次
当指定间隔为0.1秒后,10秒内将会进行100次压测。通过 -t 参数可设置压测时间,比如仅压测1秒,且压测间隔为0.1秒,命令如下:
iperf3 -c <server_ip> -i 0.1 -t 1
该参数组合适用于需要观察极短时间内(如毫秒级)带宽的突发变化或抖动,以及不希望长时间占用网络带宽的情况。
3.9.3 指定客户端端口(–cport)
客户端的源端口默认采用随机高端口,借助 –cport 参数能够指定自定义端口。例如,将源端口指定为1024,命令如下:
iperf3 -c <server_ip> --cport 1024
此参数适用于那些对出网源端口范围有严格策略限制的网络环境。
3.9.4 跳过TCP慢启动(-O,–omit)
若客户端进行压测时,想要跳过前3秒的慢启动阶段,并且每秒输出一次状态,可使用以下命令:
iperf3 -c <server_ip> -O 3 -i 1 -t 15 -P 4
图中红圈部分展示的是前3秒的压测数据,可看到标记为omitted,即已被忽略,这部分数据不会统计到最终结果中。
3.10 一些公共测试服务器
iPerf3的公共测试服务器一般由网络服务商、教育机构或者开源社区负责维护,可用于临时网络测速。适用于仅想了解单台主机带宽,且没有其他机器配合进行测试的情况。
3.10.1 官方推荐的公共测试服务器
iperf3官方推荐的公共测试服务器可参考 此列表。截至目前,其节点主要分布在欧洲、亚洲、大洋洲以及美洲。
可以发现,该列表中没有中国大陆的节点。若机器位于中国大陆,使用上述公共测试服务器进行测试时,会受到跨境网络质量拥塞的影响,导致网络延时增大、丢包率升高,最终测得的带宽也会与预期不符。例如,选用其中位于Uzbekistan Tashkent的节点进行压测,命令如下:
iperf3 -c speedtest.uztelecom.uz
从结果中可以看出,Cwnd拥塞窗口无法有效增大,这对最终的吞吐量测试产生了影响,同时从Retr字段能够看到重传数量较多。
3.10.2 第三方公共测试服务器及测速脚本
第三方公共测试服务器拥有更多的节点分布,可参考 此项目地址。该项目还提供了一个测试脚本,执行此脚本后,会依据你的出口IP位置选择距离最近的服务器节点进行测试,命令如下:
curl -s https://raw.githubusercontent.com/R0GGER/public-iperf3-servers/refs/heads/main/findtest.sh | bash
在选出最近节点后,可以自定义iperf3命令对目标节点进行压测。比如在上述截图中,脚本已帮你选定节点,此时若要进行反向多线程压测,可使用以下命令:
iperf3 -c speedtest.hkg12.hk.leaseweb.net -R -P 8
若想知晓客户端的出带宽,进行正向压测即可;若想了解客户端的入带宽,添加 -R 参数进行反向压测。此外,还可加上 -P 参数开启多线程测试 。
四、总结
当最后一次压测所生成的带宽曲线在屏幕上定格时,老张终于露出了欣慰的笑容。借助iperf3的UDP双向测试功能,他们成功且精准地定位到了跨国专线在晚高峰时段突发丢包的问题。这种从海量数据中挖掘出关键真相的能力,恰恰是这个拥有36年历史的老牌工具(iperf始创于1986年)至今仍在广泛应用的独特魅力所在。
从单线程TCP的基础测试,到多线程UDP的高强度压测;从局域网内微秒级延时的精确测量,到跨国高延迟链路中窗口大小的优化调整,我们全方位见证了iperf3在各类复杂场景下所展现出的独特价值。尤其值得注意的是,当遭遇“测速结果远低于预期”这一常见难题时,不妨参考以下实战口诀:
- TCP测不准,UDP见真章 - 突破协议栈限制,直击硬件极限
- 单线遇瓶颈,多线程破局 - 巧用 -P 参数,充分发挥多核CPU的潜能
- 高延迟作祟,窗口大小要调教 - 牢记BDP = 带宽×时延这一关键公式
- 丢包不下火线,BBR来救援 - 借助现代拥塞控制算法,有效对抗网络波动
下次再面临复杂的网络性能问题时,不妨像经验丰富的渔夫撒网捕鱼那样,将iperf3这一强大工具运用到数据的海洋中。无论是千兆光纤的极限吞吐性能,还是物联网设备发出的微弱信号,那些隐匿在协议深处的性能真相,终将在精准的流量冲击下无所遁形 。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件举报,一经查实,本站将立刻删除。
文章由技术书栈整理,本文链接:https://study.disign.me/article/202511/2.iperf3.md
发布时间: 2025-03-10