iperf3 网络性能深度揭秘:基础实践起步,攻克高延迟高丢包带宽瓶颈

一、前言

在深夜的机房中,两台服务器之间闪烁的网卡指示灯,似在默默低语。运维人员老张紧盯着监控大屏上起伏的带宽曲线,眉头拧成了个疙瘩。新部署的分布式存储系统在跨机房同步时,传输速率始终未能达到预期。他掏出手机,给同事发了条信息:“用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”命令来查看输出信息:

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>

iperf3 -c命令结果输出

压测结果中各字段的含义如下:

字段 说明
Interval 代表测试时间区间,用于明确在该时间段内进行数据传输的相关统计。
Transfer 记录数据传输量,包含sender(发送方)发送的数据量以及receiver(接收方)接收的数据量。
Bitrate 表示带宽,单位为bit,同样分为sender发送带宽与receiver接收带宽,用于衡量数据传输的速率。
Retr 即重传次数,反映了在数据传输过程中,由于各种原因导致数据包需要重新发送的次数。
Cwnd 指拥塞窗口,它的作用是限制发送方在未收到接收方确认(ACK)之前,最多能够发送的数据量,以此来控制网络拥塞情况。

3.1.2 元数据交互解析(Wireshark抓包实战)

借助Wireshark抓包工具,能够清晰地观察到iperf3在测试过程中发起了两个TCP连接。在正式传输压测数据之前,第一个TCP连接承担着至关重要的任务,它主要以json格式传输一系列参数,用于控制测试过程。客户端与服务器通过这个连接交换关键的测试配置信息,其中涵盖了测试时长、数据包大小、并行流数量等重要参数 :

Wireshark抓包实战

以图中红圈标注的参数为例,其具体含义如下:

字段 含义
“len”:131072 明确指定了数据包的长度为131072字节,该长度会影响数据传输的效率和网络负载。
“parallel”:1 表明本次测试使用的线程数为1,即采用单条数据流进行传输,而非并行传输模式。
“pacing_time”:“1000” 表示数据发送的间隔为1000毫秒,此参数对于控制数据发送节奏、避免网络拥塞具有重要意义。
“client_version”:“3.18” 显示客户端所使用的iperf3版本为3.18,不同版本可能在功能和性能上存在差异。

此外,在这个连接传输的信息中,还包含了客户端和服务器的资源使用情况,例如CPU利用率:

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来说,主要占用的则是入带宽:

Wireshark观察流量

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的角色进行互换。

这种场景常见于以下两种情况:

  1. 例如A本身没有公网IP,若要通过公网链路压测B,A若想进行外网端口监听,就需要进行DNAT映射或者使用网络穿透技术,这不仅操作繁琐,而且在许多场景下并非必要。
  2. 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