基于 Apache JMeter 5.6.3 (要求 JDK 17+),遵循行业最佳实践设计,靶向验证项目七大架构优势。
| 优势 | JMX 测试 | 核心验证点 |
|---|---|---|
| 高并发处理 | 02-auth-concurrency.jmx |
WebFlux Gateway + JWT 本地验签,500 并发 P99 < 50ms |
| Redis Cluster 热点打散 | 06-hotkey-instant-upload.jmx |
HotKeyUtil 3-shard 分散,1000 并发秒传无热点 |
| 读写分离 | 05-metadata-mixed.jmx |
MySQL 主从架构,从库承担 70%+ 读流量 |
| 秒传加速 | 03-upload-small.jmx |
upload:hash 缓存,1GB 文件二次上传 ~15ms (4666x) |
| 大文件分片上传 | 04-upload-multipart.jmx |
S3 Multipart + UUIDv7,10 片并发上传 |
| 稳定性 | 07-soak-endurance.jmx |
30 分钟持续负载,无内存泄漏、GC 不恶化 |
| 限流保护 | 08-spike-test.jmx |
Sentinel 熔断限流,尖峰后自动恢复 |
| API 完整性 | 00-smoke-test.jmx |
33 个 API 端点端到端流程验证(含 302 跳转 + 代理回退) |
| 延迟基线 | 01-baseline-latency.jmx |
1→5→20→50 并发阶梯,建立 P50/P95/P99 曲线 |
benchmark/
├── README.md # 本文件
├── config/
│ └── test.properties # JMeter 通用配置(可命令行覆盖)
├── data/
│ ├── generate.sh # 生成测试文件(1KB~100MB)
│ └── users.csv # 测试用户凭证
├── scripts/
│ ├── prepare.sh # 一键预热:启动服务+创建bucket+生成数据
│ ├── run-all.sh # 批量运行所有测试(支持单独运行)
│ └── monitor.sh # 服务端监控脚本(与JMeter并行运行)
├── jmx/
│ ├── 00-smoke-test.jmx # 冒烟测试
│ ├── 01-baseline-latency.jmx # 基线延迟测试
│ ├── 02-auth-concurrency.jmx # 认证高并发测试
│ ├── 03-upload-small.jmx # 小文件上传+秒传测试
│ ├── 04-upload-multipart.jmx # 大文件分片上传测试
│ ├── 05-metadata-mixed.jmx # 元数据混合负载测试
│ ├── 06-hotkey-instant-upload.jmx # 热点Key打散验证
│ ├── 07-soak-endurance.jmx # 耐久/浸泡测试
│ └── 08-spike-test.jmx # 尖峰冲击测试
└── reports/ # 测试报告输出目录
└── <timestamp>/ # 每次运行按时间戳分区
# 在项目根目录
docker compose up -d
# 等待所有容器 healthy (约 1-2 分钟)
docker compose ps
cd benchmark/
# 生成测试数据 + 创建测试 bucket + 预热秒传缓存
bash scripts/prepare.sh
# 冒烟测试 (检验所有 API 可用)
bash scripts/run-all.sh smoke
# 全套测试 (预计 45-60 分钟)
bash scripts/run-all.sh all
# 单独运行某个测试 (查看所有可用测试)
bash scripts/run-all.sh list
# 指定目标服务器
GATEWAY_URL=http://192.168.1.100:38080 bash scripts/run-all.sh auth
# 在 JMeter 压测期间,监控服务端指标
bash scripts/monitor.sh 300
目的: 验证所有核心 API 正常工作 并发: 1 用户 时长: ~60s
bash scripts/run-all.sh smoke
验收标准: 所有 Transaction 100% 通过,无 4xx/5xx
目的: 阶梯式增加并发,测量各 API 的 P50/P95/P99 延迟曲线 并发: 1 → 5 → 20 → 50 (四阶段,每阶段 20 次循环) 时长: ~5 min
bash scripts/run-all.sh baseline
验收标准:
| API | 1用户 | 50用户 P95 |
|---|---|---|
| GET /me | <5ms | <30ms |
| GET / (ListBuckets) | <10ms | <50ms |
| GET /{bucket}?list-type=2 | <15ms | <100ms |
目的: 压测 Gateway AuthFilter 的 JWT 验签 + Redis 黑名单查询 并发: 100 登录 + 500 认证请求 时长: ~5 min
bash scripts/run-all.sh auth
验收标准:
目的: 测试小文件上传吞吐量 + 秒传加速效果 并发: 300 循环: 每个线程上传 5 个文件 (首次正常上传 + 二次秒传)
# 10KB 文件测试
bash scripts/run-all.sh upload
# 自定义文件大小 (直接调用 JMeter)
JMETER=~/jmeter/apache-jmeter-5.6.3/bin/jmeter
$JMETER -n -t jmx/03-upload-small.jmx -q config/test.properties \
-Jfile.size.kb=100 -Jupload.threads=200 -Jupload.loops=3 \
-l reports/upload-custom.jtl
$JMETER -g reports/upload-custom.jtl -o reports/upload-custom-dashboard
关键对比数据:
| 文件大小 | 首次上传(正常) | 二次上传(秒传) | 加速比 |
|---|---|---|---|
| 10KB | ~10ms | ~5ms | 2x |
| 100KB | ~15ms | ~5ms | 3x |
| 1MB | ~50ms | ~5ms | 10x |
| 10MB | ~500ms | ~5ms | 100x |
目的: 测试 S3 Multipart Upload 完整流程 并发: 20 线程,每线程 2 次完整流程 分片: 10 片 × 512KB = 5MB/文件
bash scripts/run-all.sh multipart
# 自定义分片参数 (10片 × 10MB = 100MB文件)
JMETER=~/jmeter/apache-jmeter-5.6.3/bin/jmeter
$JMETER -n -t jmx/04-upload-multipart.jmx -q config/test.properties \
-Jmultipart.threads=10 -Jpart.size.kb=10240 -Jparts=10 \
-l reports/multipart-custom.jtl
$JMETER -g reports/multipart-custom.jtl -o reports/multipart-custom-dashboard
| 验收标准: Init < 50ms | UploadPart < 500ms | Complete < 100ms |
目的: 模拟真实用户操作分布,验证数据库读写分离 并发: 500 线程 操作分布 (真实权重): ListBuckets 40% + ListObjects 30% + GetMe 15% + Recycle 10% + CreateShare 5%
bash scripts/run-all.sh mixed
验证: 观察 MySQL 主从流量比例,从库应承担 >70% 读流量
目的: 验证 HotKeyUtil 3-shard 热点打散效果 并发: 1000 线程全命中同一 upload:hash key → 观察 Redis Cluster 节点 CPU
bash scripts/run-all.sh hotkey
验证方法:
# 压测同时运行
watch -n 2 'docker stats --no-stream --format ": CPU=" cloud-disk-redis-7000 cloud-disk-redis-7001 cloud-disk-redis-7002'
预期: 3 个 master 节点 CPU 均衡 (偏差 <20%),无单节点 100%
目的: 检测内存泄漏、GC 异常、连接池耗尽 并发: 200 线程,持续 30 分钟 操作: 混合负载 (5 种操作循环)
bash scripts/run-all.sh soak
# 自定义时长 (1小时)
JMETER=~/jmeter/apache-jmeter-5.6.3/bin/jmeter
$JMETER -n -t jmx/07-soak-endurance.jmx -q config/test.properties \
-Jsoak.threads=200 -Jduration=3600 \
-l reports/soak-1h.jtl
$JMETER -g reports/soak-1h.jtl -o reports/soak-1h-dashboard
验收标准:
/actuator/metrics 或 docker stats)注意: 耐久/尖峰测试依赖
ThreadGroup.duration控制时长,必须同时启用<boolProp name="ThreadGroup.scheduler">true</boolProp>否则 duration 会被忽略,测试无限运行。
目的: 验证 Gateway 极端并发承受能力和系统恢复能力 流程: Phase1(稳态 10 线程 × 60s) → Phase2(尖峰 2000 线程 × 30s,5s 内全部压入) → Phase3(恢复 10 线程 × 60s)
bash scripts/run-all.sh spike
实测结果 (Gateway 768MB / 384MB Heap + 16 Netty Workers):
| 阶段 | 请求数 | 错误 | P50 | P95 | P99 |
|---|---|---|---|---|---|
| Phase1 稳态 | 1,128 | 0 | 5ms | 7ms | 9ms |
| Phase2 尖峰 (2000 并发) | 7,490 | 0 | 6.7s | 34.4s | 38.7s |
| Phase3 恢复 | 1,121 | 0 | 3ms | 5ms | 5ms |
| 总计 | 9,739 | 0 | — | — | — |
验收标准:
关键优化 (从 32.6% 错误率提升至 0%):
RedissonReactiveClient — 原 isExists() 同步阻塞耗尽 Netty event loop所有 JMX 支持 ${__P(var,default)} 属性覆盖:
| 属性 | 默认值 | 说明 |
|---|---|---|
host |
localhost | 目标主机 |
gateway.port |
38080 | Gateway 端口 |
test.username |
admin | 测试用户名 |
test.password |
123456 | 测试密码 |
test.bucket |
test-benchmark | 测试 Bucket |
每个测试特有的线程/循环参数见各 JMX 文件注释。
# 示例: 高并发自定义 (测试 → 报告 两步分离)
JMETER=~/jmeter/apache-jmeter-5.6.3/bin/jmeter
# 第一步: 运行测试,生成 JTL
$JMETER -n \
-t jmx/02-auth-concurrency.jmx \
-q config/test.properties \
-Jhost=192.168.1.100 \
-Jgateway.port=38080 \
-Jauth.threads=1000 \
-Jauth.rampup=30 \
-l reports/custom.jtl
# 第二步: 从 JTL 生成 HTML 报告
$JMETER -g reports/custom.jtl -o reports/custom-dashboard
# 打开 Dashboard HTML 报告
ls reports/<timestamp>/*/index.html
# 浏览器打开查看完整 Dashboard (APDEX/KPI/Response Time/Throughput/Latency)
| 指标 | 观测方法 | JMX 对照 |
|---|---|---|
| Gateway QPS | docker stats cloud-disk-gateway |
Summary Report 的 Throughput |
| Redis CPU per node | redis-cli -p 37000 INFO CPU |
06-hotkey |
| MySQL QPS master vs slave | docker exec cloud-disk-mysql mysql -e "SHOW STATUS LIKE 'Questions'" |
05-mixed |
| JVM GC pauses | curl localhost:38081/actuator/metrics/jvm.gc.pause (object-storage) |
07-soak |
| Sentinel block count | Sentinel Dashboard (38858) | 08-spike |
| Docker network IO | docker stats --no-stream |
04-upload-multipart |
本套件遵循 性能测试金字塔:
测试数据生成遵循 独立性原则: 每个虚拟用户使用独立数据避免测试间干扰。