第二章 测试环境搭建:硬件资源规划、网络拓扑设计、监控系统部署

搭建一套靠谱的压力测试环境,其实比写测试脚本更考验功底。我见过太多团队,脚本写得花里胡哨,结果压测时网络先崩了,或者监控数据丢了——嗯,那场面挺尴尬的。

这一章,咱们就聊聊怎么把环境搭得「稳如老狗」。我会从硬件规划、网络设计、监控部署三个维度展开,把我踩过的坑和总结的经验都倒出来。

2.1 硬件资源规划:别让机器拖后腿

硬件规划这事儿,说白了就是「算账」。你得算清楚:要模拟多少用户?每笔交易消耗多少CPU和内存?网络带宽够不够?

我个人习惯先做容量估算。举个例子:

  • 目标TPS:5000笔/秒
  • 单笔交易平均耗时:50ms(含网络延迟)
  • 单笔交易CPU消耗:0.2核·秒
  • 单笔交易内存消耗:10MB

那么,压测机需要的CPU核数 = 5000 × 0.2 = 1000核。你想想看,这可不是一台机器能搞定的。我一般会拆成10台物理机,每台100核,或者用云主机按需分配。

关键指标速查表:

资源类型估算公式备注
CPUTPS × 单笔CPU消耗建议预留30%余量
内存TPS × 单笔内存消耗 × 响应时间注意GC开销
网络带宽TPS × 平均报文大小 × 8单位bps
磁盘IOPSTPS × 每次IO次数日志写入是大头

我曾经在一个项目中,只算了CPU和内存,忽略了磁盘IO。结果压测到一半,日志把磁盘写满了,监控数据全丢了。从那以后,我每次都会单独给日志盘做规划——至少500MB/s的写入能力,SSD是标配。

我的小技巧:压测机和被测系统最好物理隔离。别图省事混在一起,否则压测本身就会干扰系统表现,数据就不准了。

2.2 网络拓扑设计:延迟和带宽的博弈

网络拓扑设计,核心就两件事:延迟带宽。你想想看,如果压测机和交易系统之间隔了3层交换机,延迟多了5ms,那TPS可能直接掉20%。

我推荐一种经典拓扑:星型+旁路监控

压力测试网络拓扑图 压测集群 10台物理机 1000核 / 2TB内存 核心交换机 万兆光纤 / 低延迟 被测交易系统 4节点集群 负载均衡接入 监控系统 Prometheus + Grafana 10Gbps 10Gbps 指标采集

这个拓扑有几个要点:

  • 压测集群和被测系统直连核心交换机,中间不要串防火墙或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 环境验证:别急着开跑

环境搭好后,别急着上大规模压测。我习惯先做冒烟测试

  1. 发10笔交易,确认链路通不通
  2. 看监控数据是否正常上报
  3. 检查网络延迟和丢包率
  4. 确认告警通道是否可用

这一步花不了10分钟,但能避免你压测到一半才发现「哦,监控没连上」这种尴尬事。我曾经有一次,Prometheus配错了端口,压了半小时才发现数据全是空的——白干了。

好了,环境搭好了,监控也亮了。下一章咱们聊聊怎么写压测脚本,以及怎么设计压测场景。记住:环境是地基,地基不稳,楼盖得再高也得塌。


公众号:蓝海资料掘金营,微信deep3321