3、环境准备:压测机器与被压测机器的网络规划、硬件资源评估、操作系统参数调优
做吞吐压测,最怕什么?
不是工具不会用,也不是脚本写不好。
最怕的是——你辛辛苦苦压了一整天,结果发现瓶颈根本不在被测系统上,而是压测机自己先扛不住了。或者更惨,压测机把网络打爆了,数据全丢了。
嗯,这些坑我都踩过。今天咱们就聊聊,怎么把环境准备好,让压测结果真正可信。
3.1 网络规划:别让网线成为你的瓶颈
先问个问题:你压测的时候,网络带宽够用吗?
我见过不少团队,压测机和被测机器放在同一个机柜里,用千兆网卡。结果压到一半,网卡跑满了,CPU才用了20%。你说这算谁的锅?
核心原则:压测链路不能成为瓶颈。网络带宽至少是被测系统预期吞吐量的3倍以上。
具体怎么规划?我列几个要点:
- 同机房部署:压测机和被测机尽量放在同一个交换机下。跨机房、跨公网?延迟和丢包会让你怀疑人生。
- 万兆起步:现在万兆网卡已经很便宜了。我个人习惯,压测机一律配万兆,省心。
- 独立网段:压测流量单独走一个VLAN,别跟业务流量混在一起。否则你压测的时候,业务方会找你拼命。
- 避免NAT:压测机和被测机之间最好直连。经过NAT设备,连接数一高,端口映射表就炸了。
小技巧:压测前先用 iperf 测一下带宽。命令很简单:iperf -c 目标IP -t 30 -P 10。如果带宽达不到预期,先修网络,再谈压测。
3.2 硬件资源评估:压测机比被测机更“能吃”
很多人有个误区:觉得压测机就是发请求的,配置不用太高。
其实恰恰相反。压测机要模拟成千上万个并发用户,它自己就是个“资源黑洞”。
我举个例子。有一次我用一台4核8G的机器压一个简单的API,结果压到5000并发,压测机CPU先满了。你想想看,这数据还能用吗?
硬件评估,我一般按这个标准来:
| 资源项 | 压测机建议 | 被测机建议 | 备注 |
|---|---|---|---|
| CPU | 16核以上 | 按业务需求 | 压测机CPU用于生成请求和解析响应 |
| 内存 | 32GB以上 | 按业务需求 | 内存用于缓存连接和响应数据 |
| 磁盘 | SSD 500GB+ | SSD 或 HDD | 压测机磁盘用于写日志和结果 |
| 网卡 | 万兆 | 万兆 | 千兆在5000并发以上基本不够用 |
注意:压测机的磁盘写入速度很关键。如果压测工具把每个请求的响应都写日志,磁盘IO会成为瓶颈。我建议压测时只记录错误和关键指标,别开全量日志。
3.3 操作系统参数调优:让Linux为你让路
Linux默认的参数,是为通用场景设计的。做高并发压测?不改参数,你连1万个连接都撑不住。
为什么会这样?因为Linux默认的端口范围、文件句柄限制、TIME_WAIT处理方式,都太保守了。
3.3.1 ulimit:打开文件句柄限制
每个TCP连接,在Linux里就是一个文件句柄。默认的1024限制,你压个几百并发就满了。
改它:
# 临时生效
ulimit -n 1000000
# 永久生效,编辑 /etc/security/limits.conf
* soft nofile 1000000
* hard nofile 1000000
# 重启后生效,或者重新登录
我曾经遇到过一个案例:压测到3000并发,突然报错“Too many open files”。排查了半天,发现就是ulimit没改。嗯,这种低级错误,犯过一次就记住了。
3.3.2 tcp_tw_reuse:复用TIME_WAIT连接
TCP四次挥手后,主动关闭方会进入TIME_WAIT状态,默认持续60秒。高并发场景下,几万个TIME_WAIT连接堆积,端口全被占满了。
解决方案:开启tcp_tw_reuse。
# 编辑 /etc/sysctl.conf
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_timestamps = 1
# 生效
sysctl -p
注意:tcp_tw_reuse 只对客户端(主动发起连接的一方)有效。如果你的压测机是客户端,开启它非常有用。但如果是服务器端,需要配合 tcp_tw_recycle(不过Linux 4.12以后已经移除了这个参数)。
3.3.3 其他关键参数
除了上面两个,还有几个参数我每次压测前必调:
- net.ipv4.ip_local_port_range:扩大本地端口范围。默认32768-60999,我一般改成1024-65535。
- net.core.somaxconn:增大TCP连接队列长度。默认128,高并发下改成65535。
- net.ipv4.tcp_max_syn_backlog:增大SYN半连接队列。默认1024,改成65535。
- net.core.rmem_max / wmem_max:增大TCP读写缓冲区。默认212992,改成16777216(16MB)。
完整的sysctl配置,我贴一个模板:
# 网络核心参数
net.core.somaxconn = 65535
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
# TCP参数
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_timestamps = 1
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
# 文件句柄
fs.file-max = 1000000
避坑指南:我曾经在一台机器上同时改了tcp_tw_reuse和tcp_tw_recycle,结果导致NAT环境下的客户端连接异常。后来查资料才知道,tcp_tw_recycle在NAT环境下有严重问题。所以现在我只用tcp_tw_reuse,配合tcp_timestamps,效果已经很好了。
3.4 知识体系总览
说了这么多,你可能有点乱。我画了一张图,把环境准备的核心逻辑串起来:
说白了,环境准备就三件事:网络通、硬件够、参数对。哪一件没做好,压测结果都可能是假的。
我个人习惯,每次压测前都会写一个环境检查清单,逐项确认。别嫌麻烦,磨刀不误砍柴工。
最后提醒一句:调完参数记得重启服务或者执行 sysctl -p。我见过有人改完参数没生效,压了一整天,最后发现参数根本没加载。嗯,这种坑,踩过一次就够了。