第二章 测试环境搭建:硬件选型与系统调优

吞吐测试的结果靠不靠谱,一半看环境。我见过太多团队,代码写得挺好,结果一跑压测,瓶颈全在机器上——网卡丢包、内核参数没改、磁盘 IO 排队。说白了,环境没搭好,后面的分析全是白费功夫。

这一章,咱们就聊聊怎么搭一个「可信」的测试环境。从硬件选型到内核调优,再到网络验证,每一步我都会把踩过的坑讲清楚。

2.1 硬件选型建议

选硬件不是越贵越好,关键是匹配你的测试目标。我个人习惯先问三个问题:被测系统的瓶颈在哪?压测机需要多大并发?网络链路会不会成为短板?

2.1.1 压测机配置

压测机本身不能成为瓶颈。我建议至少满足以下规格:

组件 最低配置 推荐配置 说明
CPU 4 核 8 线程 8 核 16 线程 压测工具本身也吃 CPU,尤其是高并发场景
内存 16 GB 32 GB 或以上 连接池、请求队列、结果缓存都占内存
磁盘 SSD 256 GB NVMe 512 GB 日志写入频繁,机械盘会拖垮 IO
网卡 千兆 万兆 千兆上限约 125 MB/s,很容易跑满
注意: 压测机和被测机不要共用同一台物理机。虚拟化环境下,要确保 CPU 亲和性绑定,避免资源争抢。

2.1.2 网络设备选型

我曾经在一个项目中,压测机和服务器的网卡都是千兆,结果吞吐死活上不去。查了半天才发现,中间交换机端口协商成了百兆。嗯,这种低级错误,犯一次就够了。

选型时记住几点:

  • 网卡优先选 Intel 或 Mellanox,驱动成熟,丢包率低
  • 交换机支持流控和巨型帧(Jumbo Frame),能减少 CPU 中断
  • 如果跨机房测试,注意光模块类型和光纤跳线匹配

2.2 操作系统参数调优(Linux 内核)

硬件到位了,系统层面还得动一动。Linux 默认内核参数偏向通用场景,对高吞吐压测来说,很多限制需要放开。我每次搭环境,都会按下面几步来调。

2.2.1 网络栈调优

先看几个最关键的参数:

# 临时生效
sysctl -w net.core.somaxconn=65535
sysctl -w net.ipv4.tcp_max_syn_backlog=65535
sysctl -w net.core.netdev_max_backlog=65535
sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w net.ipv4.tcp_fin_timeout=15

# 永久生效(写入 /etc/sysctl.conf)
echo "net.core.somaxconn=65535" >> /etc/sysctl.conf
echo "net.ipv4.tcp_max_syn_backlog=65535" >> /etc/sysctl.conf
echo "net.core.netdev_max_backlog=65535" >> /etc/sysctl.conf
echo "net.ipv4.tcp_tw_reuse=1" >> /etc/sysctl.conf
echo "net.ipv4.tcp_fin_timeout=15" >> /etc/sysctl.conf
sysctl -p
我的习惯: 调完参数后,用 sysctl -a | grep <参数名> 确认生效。别信脚本,信输出。

为什么调这些?

  • somaxconn:控制 listen 队列长度。默认 128,高并发下很容易丢连接
  • tcp_max_syn_backlog:半连接队列。SYN 洪水攻击或高并发建连时,这个值小了会丢包
  • netdev_max_backlog:网卡接收队列。突发流量时,队列满了直接丢包
  • tcp_tw_reuse:允许重用 TIME_WAIT 状态的连接。压测场景下,短连接会产生大量 TIME_WAIT,不重用的话端口很快就耗尽了

2.2.2 文件描述符与进程限制

压测工具通常需要打开大量 socket。Linux 默认每个进程只能开 1024 个文件描述符,这哪够?

# 临时调整
ulimit -n 1048576

# 永久调整(/etc/security/limits.conf)
* soft nofile 1048576
* hard nofile 1048576
* soft nproc 65535
* hard nproc 65535
踩坑记录: 我曾经只改了 limits.conf,但没重启压测进程,结果 ulimit 没生效。记住,ulimit -n 只对当前 shell 和它的子进程有效。改完配置后,要么重新登录,要么重启压测服务。

2.2.3 内存与缓冲区调优

网络缓冲区太小,会导致吞吐上不去。我一般这样调:

sysctl -w net.core.rmem_default=262144
sysctl -w net.core.wmem_default=262144
sysctl -w net.core.rmem_max=16777216
sysctl -w net.core.wmem_max=16777216
sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"
sysctl -w net.ipv4.tcp_wmem="4096 65536 16777216"

简单解释一下:

  • rmem_default / wmem_default:默认的接收/发送缓冲区大小
  • rmem_max / wmem_max:最大缓冲区大小。高延迟链路(比如跨机房)需要调大这个值
  • tcp_rmem / tcp_wmem:三个值分别表示最小、默认、最大。内核会根据实际负载动态调整

2.3 网络带宽与延迟测试

环境搭好了,得先验证网络能不能扛住。别等到压测跑起来才发现网卡是瓶颈。我常用的工具是 iperf3 和 ping,但用法上有讲究。

2.3.1 带宽测试(iperf3)

iperf3 是目前最主流的带宽测试工具。用法很简单:

# 服务端(被测机)
iperf3 -s -p 5201

# 客户端(压测机)
iperf3 -c 192.168.1.100 -p 5201 -t 30 -P 4

参数说明:

  • -t 30:测试 30 秒。太短测不准,太长浪费时间
  • -P 4:4 个并行流。单流可能跑不满带宽,多流更接近真实场景

关键指标:

  • 带宽利用率:实测带宽 / 理论带宽 × 100%。低于 80% 说明有问题
  • 重传率:Retr 列的值 / 总包数。超过 0.1% 就要排查了
  • CPU 占用:如果 CPU 先跑满了,说明网卡 offload 没开或者驱动有问题

2.3.2 延迟测试(ping 与 mtr)

ping 测延迟,但别只测一次。我习惯这样:

# 连续 ping 100 次,看最小、最大、平均延迟和丢包率
ping -c 100 192.168.1.100

# 用 mtr 看每一跳的延迟和丢包
mtr -r -c 50 192.168.1.100

mtr 比 ping 强在哪?它能显示路径上每一跳的延迟和丢包。我曾经用 mtr 发现,压测机和服务器之间有个交换机丢包 5%,换掉之后吞吐直接翻倍。

2.3.3 测试结果解读

拿到数据后,怎么判断网络是否合格?我一般用这个标准:

场景 带宽利用率 延迟(RTT) 丢包率 重传率
同机房 ≥ 95% < 0.5 ms 0% < 0.01%
同城跨机房 ≥ 90% < 3 ms < 0.01% < 0.05%
跨地域 ≥ 80% < 50 ms < 0.1% < 0.5%
小技巧: 如果带宽利用率低但 CPU 没跑满,试试调大 iperf3 的窗口大小:-w 1M。TCP 窗口太小,高延迟链路下带宽是跑不上去的。

2.4 本章知识体系

下面这张图,把环境搭建的核心逻辑串起来了。你可以把它当作检查清单:

测试环境搭建知识体系 搭建可信的吞吐测试环境 硬件选型 操作系统调优 网络验证 压测机 CPU / 内存 / 磁盘 / 网卡 网络设备:交换机 / 光模块 / 跳线 网络栈:somaxconn / backlog / tw_reuse 文件描述符 / 进程限制 / 缓冲区 带宽测试:iperf3 多流 / 窗口调优 延迟测试:ping / mtr 逐跳分析 环境基线报告(带宽 / 延迟 / 丢包) 💡 每个环节都要记录基线数据 硬件更换或网络变更后,重新跑一遍验证流程

环境搭建这件事,看着琐碎,但每一条参数、每一个测试步骤,都可能决定你后续分析的成败。我自己的经验是:花半天把环境调好,后面能省三天排查问题的时间。别嫌麻烦,值得的。