第三章 测试环境搭建:硬件、软件与监控

环境搭建这事,看着像体力活,其实坑最多。我见过不少团队,脚本写得漂亮,压测一跑就崩——不是被测系统崩,是监控先挂了。说白了,环境搭不好,后面的数据全是废的。

这一章,咱们把硬件规划、软件配置、网络拓扑、监控部署这四个环节拆开揉碎。我会把我在项目中踩过的坑、试过的方案,都摊开来讲。

3.1 硬件环境规划

硬件选型,核心就一句话:别让硬件成为瓶颈,也别让硬件成为浪费。

我个人习惯,先算三笔账:

  • 目标吞吐量:比如你要测 10 万 QPS,那 CPU、内存、网卡都得按这个量级配。
  • 资源消耗模型:被测服务是 CPU 密集还是 IO 密集?这决定了你是堆核还是堆内存。
  • 压测机与被测机隔离:压测机不能跟被测服务抢资源,否则结果不准。

我建议的硬件配置参考(以中等规模压测为例):

角色 CPU 内存 磁盘 网卡
压测机(主控) 8 核以上 16 GB SSD 500 GB 万兆
压测机(执行器) 4 核 × N 台 8 GB/台 SSD 256 GB 千兆
被测服务节点 16 核以上 32 GB SSD 1 TB 万兆
监控服务器 4 核 8 GB SSD 500 GB 千兆

一个小技巧:压测机的磁盘一定要用 SSD。我曾经用机械盘跑高并发日志写入,结果压测机自己 IO 打满了,压测数据全丢了。嗯,从那以后我再也不敢省硬盘钱。

3.2 软件环境配置

软件环境,核心是版本一致和参数调优。你想想看,压测环境跟生产环境差了三个大版本,测出来的数据能信吗?

3.2.1 操作系统层

  • 内核参数:调整 net.core.somaxconn、net.ipv4.tcp_tw_reuse、fs.file-max 等。
  • 文件描述符:压测机和服务端都要放开 ulimit,建议设到 100 万以上。
  • 时钟同步:所有机器必须 NTP 同步,否则监控数据时间戳对不上。
# 我常用的内核参数调整(/etc/sysctl.conf)
net.core.somaxconn = 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
fs.file-max = 1048576

3.2.2 中间件与数据库

我记得有一次压测 Redis,默认配置下连接数一上去就报错。后来才发现 maxclients 没改。说白了,中间件的默认参数都是为低负载设计的,压测前必须调。

组件 关键参数 建议值
Nginx worker_connections 65535
MySQL max_connections 2000+
Redis maxclients 50000
Tomcat maxThreads 1000

注意:参数调大后,要确认系统资源(内存、文件句柄)够用。我曾经把 MySQL 的 max_connections 调到 5000,结果内存直接爆了。调参要循序渐进,别一把梭。

3.3 网络拓扑设计

网络拓扑,说白了就是数据怎么走。设计不好,网络延迟会吃掉你的吞吐量。

我建议的拓扑原则:

  1. 压测机与被测服务尽量同机房,减少公网延迟干扰。
  2. 监控流量走独立网段,别跟业务流量抢带宽。
  3. 避免单点:压测机、监控服务器都要做冗余。
吞吐测试网络拓扑结构图 吞吐测试网络拓扑结构图 压测机集群 主控节点 × 1 执行节点 × N 万兆网卡 核心交换机 万兆上行 被测服务集群 应用节点 × 3 数据库主从 缓存集群 监控服务器 Prometheus + Grafana 独立千兆网段 拓扑设计要点 • 压测机与被测服务同机房,减少延迟 • 监控流量走独立网段,不干扰业务 • 核心交换机做冗余,避免单点故障

避坑指南:我曾经在压测时发现延迟忽高忽低,查了半天,原来是监控 Agent 跟业务流量抢带宽。从那以后,我坚持监控走独立网段,哪怕多拉一根线也值。

3.4 监控系统部署

监控系统,是压测的眼睛。没有监控,你就是在盲测。

我常用的监控栈:

  • 指标采集:Prometheus + Node Exporter + 业务自定义 Exporter
  • 可视化:Grafana(预置仪表盘)
  • 链路追踪:Jaeger 或 SkyWalking(用于分析慢调用)
  • 日志聚合:ELK(Elasticsearch + Logstash + Kibana)

3.4.1 关键监控指标

维度 指标 说明
系统层 CPU、内存、磁盘 IO、网络带宽 基础资源使用率
应用层 QPS、响应时间、错误率、线程数 业务性能指标
中间件层 连接数、队列深度、缓存命中率 组件健康状态
JVM 层 GC 次数、堆内存、元空间 Java 应用专用

3.4.2 部署示例(Docker Compose)

version: '3'
services:
  prometheus:
    image: prom/prometheus:latest
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
      - "9090:9090"

  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin

  node-exporter:
    image: prom/node-exporter:latest
    ports:
      - "9100:9100"

注意:监控系统本身也会消耗资源。压测时,监控采集频率别设太高——我见过有人把 Prometheus 的 scrape_interval 设成 1 秒,结果监控服务器 CPU 先打满了。建议压测期间设 5-10 秒,分析时再调细。

3.5 环境验证清单

环境搭完,别急着跑压测。先做一轮验证,确保所有环节都通。

  1. 网络连通性:压测机到被测服务的端口通不通?延迟多少?
  2. 参数生效:内核参数、中间件配置是否已加载?
  3. 监控数据:Grafana 上能看到指标吗?时间戳对不对?
  4. 小规模预压:先跑 100 并发,确认系统响应正常。

我个人的环境验证脚本(简化版):

#!/bin/bash
# 网络检查
nc -zv 192.168.1.100 8080
# 内核参数检查
sysctl net.core.somaxconn
# 监控检查
curl -s http://localhost:9090/api/v1/query?query=up | jq .
# 小规模压测
ab -n 1000 -c 100 http://192.168.1.100:8080/api/test