性能基准:网络性能指标定义与基准测试方法论

做网络性能分析,第一件事是什么?不是抓包,不是看代码,而是先搞清楚——你到底要测什么。我见过太多人上来就跑 iperf3,看着屏幕上的数字觉得"还行",结果上线一压就崩。说白了,你连指标都没对齐,后面的分析全是空中楼阁。

这一章,我们就来把网络性能的四个核心指标掰开揉碎,再聊聊怎么用 iperf3 和 netperf 做靠谱的基准测试。嗯,都是我在项目中踩过坑之后总结出来的经验。

1. 四个核心指标:吞吐量、延迟、PPS、连接数

网络性能不是"快不快"这么简单。你得从四个维度去看,缺一个都不完整。

指标 定义 单位 典型场景
吞吐量 单位时间内成功传输的数据量 bps / MB/s 大文件传输、视频流
延迟 数据从发送端到接收端的单向耗时 ms / μs 实时通信、交易系统
PPS 每秒处理的数据包数量 packets/s 网关、防火墙、负载均衡
连接数 系统同时维持的 TCP 连接数量 个 Web 服务器、数据库连接池

关键认知:这四个指标之间是相互制约的。高吞吐量不一定意味着低延迟,高 PPS 处理能力也不等于高连接数。你优化了一个指标,另一个可能反而变差。

1.1 吞吐量——最容易被误解的指标

吞吐量是大多数人第一个看的指标。但我得说一句:只看吞吐量,你可能会被误导。

举个例子。我在调优一个视频分发平台时,发现 iperf3 测出来的吞吐量能跑到 9.8 Gbps,但实际业务流量一上去,用户还是卡。为什么?因为 iperf3 用的是大包(1460 字节 payload),而业务里有很多小包(64 字节)。大包能跑满带宽,小包就不一定了。

所以,测吞吐量时一定要明确:包大小是多少? 不同包大小下的吞吐量,反映的是不同层面的性能。

1.2 延迟——毫秒级的差距就是生死

延迟这东西,在金融交易系统里就是钱。我记得有一次帮一家券商做性能评估,他们的交易链路要求端到端延迟不超过 100 微秒。我们用 netperf 的 TCP_RR 测试,发现内核协议栈的延迟在 50-80 微秒之间波动。嗯,这个数字看起来还行,但峰值抖动到了 200 微秒——这就不能接受了。

延迟测试要关注两个值:平均值和尾延迟(P99/P999)。平均值好看不代表系统稳定,尾延迟才是真正的杀手。

1.3 PPS——小包场景下的硬指标

PPS 是很多人忽略的指标。你想想看,一个 64 字节的小包,和 1460 字节的大包,在网卡层面处理的开销其实差不多——都要走一遍 DMA、中断、协议栈。但吞吐量上,64 字节包只能跑到大包的 1/20 左右。

我曾经在测试一个 DPDK 改造方案时,发现原生内核协议栈的 PPS 上限大概在 1.5M 左右(单核),再高就开始丢包了。而 DPDK 方案能跑到 10M+。这个差距,就是协议栈处理路径的差异带来的。

我的经验:如果你的业务以小包为主(比如 DNS、HTTP 短连接),PPS 比吞吐量更重要。建议先用 64 字节包做压力测试,看看系统能扛多少 PPS。

1.4 连接数——并发能力的试金石

连接数这个指标,很多人把它和并发数混为一谈。其实不对。连接数指的是系统同时维持的 TCP 连接数量,而并发数是指同时处理的请求数量。

一个典型的场景:Nginx 作为反向代理,可以维持 10 万个长连接,但真正活跃的请求可能只有几百个。这时候瓶颈往往不在 CPU,而在内存——每个 TCP 连接都要占用一个 socket 缓冲区,默认的 tcp_rmem 和 tcp_wmem 加起来可能超过 200KB。10 万个连接,光缓冲区就要 20GB 内存。

2. 基准测试方法论:iperf3 与 netperf

工具选对了,测试就成功了一半。我个人习惯用 iperf3 做吞吐量测试,用 netperf 做延迟和 PPS 测试。为什么?因为各有专长。

2.1 iperf3——吞吐量测试的首选

iperf3 简单、直接、结果清晰。但简单不等于随便跑。我见过有人直接在两个机器上跑 iperf3,中间隔了 10 跳路由器,然后拿着结果说"网络带宽是 100Mbps"——这能信吗?

正确的做法:

  1. 直连测试:两台机器用网线直连,排除中间设备干扰。
  2. 多流测试:单流可能跑不满带宽,用 -P 4 或 -P 8 开多个并行流。
  3. 双向测试:用 -d 或 --bidir 同时测上下行。
  4. 不同包大小:用 -l 参数调整包大小,从 64 到 1460 都测一遍。
# 服务端
iperf3 -s -p 5201

# 客户端:单流 TCP 测试,包大小 1460
iperf3 -c 192.168.1.100 -p 5201 -t 30 -l 1460

# 客户端:多流测试,8 个并行流
iperf3 -c 192.168.1.100 -p 5201 -t 30 -P 8

# 客户端:UDP 测试,指定带宽 1Gbps
iperf3 -c 192.168.1.100 -p 5201 -u -b 1G -l 1400

注意:iperf3 的 UDP 测试默认不限制带宽,如果不加 -b 参数,它会拼命发包,导致测试结果失真。另外,UDP 测试的结果里有个 "Jitter" 字段,那是抖动值,不是延迟,别搞混了。

2.2 netperf——延迟和 PPS 的利器

netperf 比 iperf3 更灵活,尤其适合做延迟和 PPS 测试。它的测试模式很多,我常用的就三个:

测试模式 命令 测什么
TCP_STREAM netperf -H server -l 30 -t TCP_STREAM 吞吐量
TCP_RR netperf -H server -l 30 -t TCP_RR 请求-响应延迟
TCP_CRR netperf -H server -l 30 -t TCP_CRR 连接建立+请求-响应延迟

TCP_RR 测的是已建立连接上的请求-响应延迟,适合评估长连接场景。TCP_CRR 则包含了三次握手的时间,适合评估短连接场景。这两个值之间的差距,就是连接建立的代价。

我记得有一次,我们在优化一个 HTTP 网关,发现 TCP_CRR 的延迟比 TCP_RR 高了 3 倍。追下去发现是 listen 队列的 backlog 设置太小,导致三次握手阶段有重传。调大 backlog 后,TCP_CRR 的延迟降了 40%。

3. 测试环境搭建与校准

环境搭不好,测试就是白做。我总结了一个"三校准"原则:硬件校准、系统校准、工具校准。

3.1 硬件校准

  • 网卡确认:用 ethtool eth0 查看网卡速率、双工模式、驱动版本。确保两端协商一致。
  • PCIe 带宽:用 lspci -vvv -s 网卡地址 查看 PCIe 链路宽度和速率。x8 Gen3 的理论带宽是 8GB/s,如果显示 x1 Gen2,那网卡性能直接砍半。
  • 中断绑定:用 cat /proc/interrupts | grep eth0 查看中断分布。多队列网卡要把中断分散到不同 CPU 上。
# 查看网卡信息
ethtool eth0

# 查看 PCIe 链路状态
lspci -vvv -s 02:00.0 | grep -i "width\|speed"

# 设置 RPS(Receive Packet Steering)分散中断
echo f > /sys/class/net/eth0/queues/rx-0/rps_cpus

3.2 系统校准

系统参数对测试结果影响巨大。我每次做基准测试前,都会检查这几个关键参数:

参数 推荐值 说明
net.core.rmem_max 134217728 接收缓冲区最大值,128MB
net.core.wmem_max 134217728 发送缓冲区最大值,128MB
net.ipv4.tcp_rmem 4096 87380 134217728 TCP 接收缓冲区(min default max)
net.ipv4.tcp_wmem 4096 65536 134217728 TCP 发送缓冲区(min default max)
net.core.netdev_budget 600 NAPI 每次轮询处理的包数
net.core.somaxconn 65535 listen 队列最大长度

一个小技巧:测试前先跑一次 sysctl -w net.ipv4.tcp_timestamps=0 关闭时间戳选项。时间戳会在每个 TCP 头部增加 12 字节,关闭后能减少 CPU 开销,让测试结果更接近硬件极限。

3.3 工具校准

工具本身也会引入误差。我习惯在正式测试前做一次"回环测试"——在同一台机器上跑客户端和服务端,看看工具自身的开销有多大。

# 回环测试:服务端和客户端都在本机
# 终端1
iperf3 -s -p 5201 -B 127.0.0.1

# 终端2
iperf3 -c 127.0.0.1 -p 5201 -t 10

# 结果应该接近 40Gbps+(取决于内存带宽)
# 如果远低于这个值,说明系统或工具有问题

回环测试能帮你排除网卡和线缆的问题。如果回环测试结果正常,但直连测试结果很差,那问题大概率出在网卡、驱动或线缆上。

4. 知识体系总览

下面这张图,把本章的核心逻辑串起来了。你可以把它当作一个检查清单——做性能测试前,对着它过一遍,基本不会漏东西。

网络性能基准测试知识体系 吞吐量 延迟 PPS 连接数 iperf3:吞吐量 / UDP 抖动 netperf:延迟 / PPS / 连接 三校准:硬件 → 系统 → 工具 执行测试:直连 / 多流 / 双向 / 不同包大小 / 多次取均值 ⚠ 每次修改系统参数后,必须重启 netserver/iperf3 服务端,否则参数不生效

5. 避坑指南:我踩过的几个坑

最后,分享几个我实际项目中遇到的坑,希望能帮你少走弯路。

坑一:CPU 亲和性没设置

我曾经在 48 核的机器上跑 netperf,结果发现延迟忽高忽低。排查了半天,发现是客户端和服务端跑在了同一个物理核的兄弟线程上。用 taskset 绑定到不同 NUMA 节点后,延迟稳定了 30%。

坑二:中断合并(coalescing)没关

网卡默认的中断合并策略是为了降低 CPU 使用率,但会引入额外的延迟。用 ethtool -C eth0 rx-usecs 0 tx-usecs 0 关掉合并后,延迟从 200μs 降到了 50μs。当然,CPU 使用率会上升,但基准测试要的是极限性能,不是省电。

坑三:iperf3 的 UDP 测试结果不可重复

iperf3 的 UDP 测试对系统时钟敏感。如果系统时钟有漂移,结果会忽高忽低。我建议用 --omit 5 跳过前 5 秒的数据,等系统稳定后再记录。另外,UDP 测试最好配合 chronyd 或 ptpd 做时间同步。