3. 测试环境搭建:单机、分布式、Docker 与监控

环境搭建这事儿,看着基础,其实坑最多。我见过不少团队,性能问题还没摸到边,先被环境折腾掉一周。说白了,环境搭不对,后面的测试数据全是废的。

这一章,我把四种常见部署模式都过一遍。单机、分布式、Docker 容器化,外加监控工具链。每种模式我都会给出实际配置参数和避坑点。

3.1 单机环境配置

单机环境适合做功能验证和小规模压测。别小看它,很多性能瓶颈在单机上就能暴露出来。

3.1.1 硬件与操作系统调优

我个人习惯,拿到一台新机器先做三件事:

  • 关闭 NUMA 平衡:在 BIOS 或 OS 层面关闭,避免内存跨节点访问增加延迟。
  • 调整文件描述符上限:ulimit -n 65535,否则高并发下 socket 会报错。
  • 设置内核参数:net.core.somaxconn、net.ipv4.tcp_tw_reuse 这些必须改。

核心参数速查表

参数推荐值说明
vm.swappiness10减少 swap 使用,优先用内存
net.core.somaxconn1024TCP 连接队列长度
net.ipv4.tcp_tw_reuse1复用 TIME_WAIT 连接
fs.file-max1000000系统级文件句柄上限

3.1.2 应用服务器配置

以 Tomcat 为例,我一般这样改 server.xml:

<Connector port="8080" protocol="HTTP/1.1"
           maxThreads="400"
           minSpareThreads="50"
           acceptCount="200"
           connectionTimeout="20000"
           maxConnections="10000" />

注意 maxConnections 别设太大,否则操作系统先扛不住。我曾经在一台 4C8G 的机器上把 maxConnections 设成 20000,结果压测时 CPU 全耗在上下文切换上,吞吐量反而下降。

3.2 分布式环境配置

单机测不出水平扩展能力。分布式环境才是性能调优的主战场。

3.2.1 网络与时钟同步

分布式环境第一个坑:时钟不同步。日志时间戳对不上,排查问题能让你崩溃。

  • 所有节点安装 NTP 服务,指向同一台内网时间服务器。
  • 网络延迟测试:ping 延迟 < 1ms,iperf 带宽 > 1Gbps。

3.2.2 负载均衡层

我常用 Nginx 做反向代理,配置要点:

upstream backend {
    least_conn;  # 最少连接数算法
    server 192.168.1.10:8080 weight=5;
    server 192.168.1.11:8080 weight=3;
    keepalive 32;
}

server {
    listen 80;
    location / {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
    }
}

这里 keepalive 32 很关键。不加这个,每次请求都新建 TCP 连接,吞吐量直接腰斩。

3.2.3 分布式缓存与数据库

Redis 集群至少 3 主 3 从,MySQL 做读写分离。我习惯用 ProxySQL 做数据库中间件,配置简单,还能在线改规则。

经验之谈:分布式环境下,网络 I/O 往往是第一瓶颈。先压测网络链路,再调应用层。别上来就调 JVM 参数,方向错了。

3.3 Docker 容器化部署

容器化让环境复现变得简单。但性能隔离是个大问题。

3.3.1 Dockerfile 与资源限制

一个标准的 Java 应用 Dockerfile:

FROM openjdk:11-jre-slim
COPY target/app.jar /app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-Xmx512m", "-Xms512m", "-jar", "/app.jar"]

运行时要加资源限制:

docker run -d --name myapp \
  --cpus="2.0" \
  --memory="1g" \
  --memory-swap="1g" \
  -p 8080:8080 myapp:latest

--memory-swap="1g" 这个参数很多人忽略。不设的话,容器会用宿主机 swap,性能抖动很厉害。

3.3.2 Docker Compose 编排

多服务场景用 Compose 最方便:

version: '3.8'
services:
  app:
    build: .
    ports:
      - "8080:8080"
    depends_on:
      - redis
      - mysql
  redis:
    image: redis:6-alpine
    ports:
      - "6379:6379"
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root123

注意:Docker 默认网络模式是 bridge,性能比 host 模式差 10%-15%。压测时建议用 --network=host,或者用 macvlan 驱动。

3.4 监控工具安装与配置

没有监控,性能调优就是盲人摸象。我常用的三件套:Prometheus + Grafana + Node Exporter。

3.4.1 Prometheus 部署

Prometheus 负责采集指标。安装很简单:

# 下载并解压
wget https://github.com/prometheus/prometheus/releases/download/v2.45.0/prometheus-2.45.0.linux-amd64.tar.gz
tar xvf prometheus-*.tar.gz
cd prometheus-*

# 启动
./prometheus --config.file=prometheus.yml &

配置文件 prometheus.yml 核心部分:

scrape_configs:
  - job_name: 'node'
    static_configs:
      - targets: ['localhost:9100']
  - job_name: 'app'
    metrics_path: '/actuator/prometheus'
    static_configs:
      - targets: ['192.168.1.10:8080']

3.4.2 Grafana 可视化

Grafana 负责展示。安装后导入 Node Exporter Full 模板(ID: 1860),5 分钟就能看到 CPU、内存、网络、磁盘的全景图。

我的监控清单

指标来源告警阈值
CPU 使用率Node Exporter> 80% 持续 5 分钟
内存使用率Node Exporter> 90%
磁盘 IO 等待Node Exporter> 30%
应用响应时间 P99Micrometer> 500ms
错误率应用指标> 1%

3.4.3 其他实用工具

  • htop:实时看进程 CPU/内存,比 top 直观。
  • iotop:定位哪个进程在疯狂写磁盘。
  • netstat / ss:查端口、连接状态,ss -s 看连接数汇总。
  • jmeter + InfluxDB:压测结果实时入库,Grafana 上画曲线。

避坑指南:我曾经在生产环境装完 Prometheus 忘了配 retention,结果磁盘被监控数据撑爆。现在我的习惯是:--storage.tsdb.retention.time=30d,外加磁盘告警。

3.5 环境拓扑总览

下面这张图,把本章涉及的环境组件和关系串起来。你搭建时照着这个结构来,不会乱。

吞吐测试环境拓扑总览 压测客户端 JMeter / wrk / ab 负载均衡层 Nginx / HAProxy 应用节点 1 Tomcat / Spring Boot 应用节点 2 Tomcat / Spring Boot 应用节点 3 Tomcat / Spring Boot 缓存层 Redis Cluster 数据库层 MySQL / PostgreSQL 监控与可视化 Prometheus + Grafana 说明: 1. 压测客户端 → 负载均衡 → 应用节点 → 缓存/数据库,构成完整请求链路。 2. 监控层从所有节点采集指标,用于性能分析和瓶颈定位。 3. 虚线表示监控数据流,实线表示业务数据流。

环境搭好只是第一步。下一件事,就是跑一轮基准测试,拿到基线数据。没有基线,后面所有的调优都说不清效果。