第二章 测试环境搭建:硬件资源规划、网络拓扑设计、监控系统部署
搭建一套靠谱的压力测试环境,其实比写测试脚本更考验功底。我见过太多团队,脚本写得花里胡哨,结果压测时网络先崩了,或者监控数据丢了——嗯,那场面挺尴尬的。
这一章,咱们就聊聊怎么把环境搭得「稳如老狗」。我会从硬件规划、网络设计、监控部署三个维度展开,把我踩过的坑和总结的经验都倒出来。
2.1 硬件资源规划:别让机器拖后腿
硬件规划这事儿,说白了就是「算账」。你得算清楚:要模拟多少用户?每笔交易消耗多少CPU和内存?网络带宽够不够?
我个人习惯先做容量估算。举个例子:
- 目标TPS:5000笔/秒
- 单笔交易平均耗时:50ms(含网络延迟)
- 单笔交易CPU消耗:0.2核·秒
- 单笔交易内存消耗:10MB
那么,压测机需要的CPU核数 = 5000 × 0.2 = 1000核。你想想看,这可不是一台机器能搞定的。我一般会拆成10台物理机,每台100核,或者用云主机按需分配。
关键指标速查表:
| 资源类型 | 估算公式 | 备注 |
|---|---|---|
| CPU | TPS × 单笔CPU消耗 | 建议预留30%余量 |
| 内存 | TPS × 单笔内存消耗 × 响应时间 | 注意GC开销 |
| 网络带宽 | TPS × 平均报文大小 × 8 | 单位bps |
| 磁盘IOPS | TPS × 每次IO次数 | 日志写入是大头 |
我曾经在一个项目中,只算了CPU和内存,忽略了磁盘IO。结果压测到一半,日志把磁盘写满了,监控数据全丢了。从那以后,我每次都会单独给日志盘做规划——至少500MB/s的写入能力,SSD是标配。
我的小技巧:压测机和被测系统最好物理隔离。别图省事混在一起,否则压测本身就会干扰系统表现,数据就不准了。
2.2 网络拓扑设计:延迟和带宽的博弈
网络拓扑设计,核心就两件事:延迟和带宽。你想想看,如果压测机和交易系统之间隔了3层交换机,延迟多了5ms,那TPS可能直接掉20%。
我推荐一种经典拓扑:星型+旁路监控。
这个拓扑有几个要点:
- 压测集群和被测系统直连核心交换机,中间不要串防火墙或IPS——延迟会翻倍。我吃过这个亏,加了防火墙后TPS从5000掉到3200,排查了一整天。
- 监控系统旁路接入,通过交换机镜像端口或Agent采集数据,不影响主链路。
- 带宽要留余量。如果压测流量是5Gbps,交换机端口至少配10Gbps。我曾经用千兆网口压测,结果网卡先成了瓶颈,CPU才用到30%就上不去了。
注意:千万别把监控流量和压测流量混在一个网段。我建议监控走独立VLAN,避免监控数据包冲击压测链路。
2.3 监控系统部署:Prometheus + Grafana
监控系统是压测的「眼睛」。没有监控,你就是在盲打。我个人最常用的组合是Prometheus + Grafana,开源、灵活、生态好。
2.3.1 Prometheus 部署要点
Prometheus 的部署其实不复杂,但有几个坑要注意:
# prometheus.yml 核心配置
global:
scrape_interval: 5s # 采集间隔,压测时建议5秒,别设太长
evaluation_interval: 5s
scrape_configs:
- job_name: 'trade-system'
static_configs:
- targets: ['192.168.1.10:8080', '192.168.1.11:8080']
metrics_path: '/actuator/prometheus' # Spring Boot 标准路径
- job_name: 'node-exporter'
static_configs:
- targets: ['192.168.1.10:9100', '192.168.1.11:9100']
这里有个细节:scrape_interval 我习惯设5秒。为什么不是1秒?因为Prometheus是拉模式,太频繁会加重被采集系统的负担。压测时系统本身就很忙,别让监控成为压死骆驼的最后一根稻草。
关键指标清单:
| 指标类别 | 具体指标 | 采集方式 |
|---|---|---|
| 系统资源 | CPU使用率、内存使用率、磁盘IO、网络带宽 | Node Exporter |
| JVM指标 | GC次数、堆内存、线程数、类加载 | JMX Exporter / Micrometer |
| 业务指标 | TPS、响应时间、错误率、队列深度 | 应用埋点 |
| 中间件指标 | 连接数、吞吐量、延迟 | 各中间件Exporter |
我曾经遇到过一个情况:压测时GC频繁,但Prometheus采集间隔设了30秒,根本抓不到瞬时的GC停顿。后来改成5秒,问题立刻暴露了。所以,采集粒度要跟压测的节奏匹配。
2.3.2 Grafana 仪表盘设计
Grafana 的仪表盘,我建议按分层设计:
- 第一层:全局概览——TPS、响应时间、错误率、CPU/内存总览。一眼看出系统健康度。
- 第二层:资源详情——每台机器的CPU、内存、磁盘、网络。定位是哪台机器出了问题。
- 第三层:JVM/业务详情——GC详情、线程状态、业务队列。深入分析根因。
举个例子,TPS的查询语句可以这样写:
# 计算每秒交易量
sum(rate(trade_requests_total[1m])) by (instance)
# 计算P99响应时间
histogram_quantile(0.99, sum(rate(trade_response_time_bucket[1m])) by (le, instance))
我的经验:在Grafana里加一个「压力测试状态」面板。用颜色标识:绿色(正常)、黄色(告警)、红色(危险)。这样你扫一眼就知道当前压测是否安全,不用盯着十几个图表看。
2.3.3 告警规则配置
告警不是越多越好。我见过有人配了50条告警规则,结果压测时告警刷屏,真正的问题反而被淹没了。
我一般只配这几条核心规则:
# 告警规则示例
groups:
- name: stress-test-alerts
rules:
- alert: HighErrorRate
expr: rate(trade_errors_total[1m]) / rate(trade_requests_total[1m]) > 0.01
for: 1m
annotations:
summary: "错误率超过1%"
- alert: HighResponseTime
expr: histogram_quantile(0.99, rate(trade_response_time_bucket[1m])) > 2
for: 30s
annotations:
summary: "P99响应时间超过2秒"
- alert: HighCPUUsage
expr: 100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[1m])) * 100) > 90
for: 2m
annotations:
summary: "CPU使用率超过90%"
你看,每条规则都有for字段——持续一段时间才触发告警。这能避免偶发抖动导致的误报。我刚开始做压测时没加这个,结果网络抖动一下,告警就炸了,后来学乖了。
重要提醒:压测结束后,记得关闭告警通知。否则半夜收到告警短信,爬起来一看是压测残留数据,那感觉...嗯,你懂的。
2.4 环境验证:别急着开跑
环境搭好后,别急着上大规模压测。我习惯先做冒烟测试:
- 发10笔交易,确认链路通不通
- 看监控数据是否正常上报
- 检查网络延迟和丢包率
- 确认告警通道是否可用
这一步花不了10分钟,但能避免你压测到一半才发现「哦,监控没连上」这种尴尬事。我曾经有一次,Prometheus配错了端口,压了半小时才发现数据全是空的——白干了。
好了,环境搭好了,监控也亮了。下一章咱们聊聊怎么写压测脚本,以及怎么设计压测场景。记住:环境是地基,地基不稳,楼盖得再高也得塌。
公众号:蓝海资料掘金营,微信deep3321