JMeter使用心得

压测结果不稳定的 5 大原因

  1. 网络抖动 --- 压测机与被测服务跨 AZ/跨机房,RTT 波动大,TP99 出现毛刺;解法:同机房同网段,延迟 < 1ms
  2. JVM 预热不充分 --- JIT 编译器需 5-30 分钟才能把热点代码编译成机器码,预热前后性能差 3-5 倍;解法:压测前先跑 10-15 分钟低负载预热
  3. 连接池打满 --- HikariCP 默认 max-pool-size=10,高并发下连接耗尽,后续请求排队;解法:maximum-pool-size=50,压测前按峰值评估调大
  4. 缓存冷启动 --- Redis/本地缓存为空时所有请求打到 DB,首次压测 RT 500ms vs 预热后 100ms,差 5 倍;解法:压测前跑热点数据预热缓存
  5. GC 抖动 --- 高并发对象分配速率高,频繁 Stop The World,RT 曲线出现规律尖峰;解法:-XX:MaxGCPauseMillis=100 调优 G1

让结果稳定的 5 个关键做法

  1. 三遍取中位数基线法 --- 单次压测无意义,取三轮中位数再取中位数(如:205ms / 208ms / 203ms → 最终 205ms);偏差 > 10% 阻断发布
  2. 专有压测环境隔离 --- 独立集群独立数据库,禁止与测试/开发环境混用,避免其他业务干扰
  3. 监控先行,压测前健康检查 --- CPU < 30%、JVM 堆 < 60%、DB 连接空闲、Redis 正常;确认干净后再开始正式压测
  4. 数据与生产等量级 --- 预置足够账户/库存(如 10 万用户账户),避免数据量不足导致锁竞争和索引效率失真
  5. 四大指标看 TP99 --- 不只看平均值,TP50 < 200ms / TP90 < 500ms / TP99 < 1000ms / Error% < 0.1%,四指标全部达标才算通过

1. JMeter 分布式压测架构

架构:Controller + Slave(多台机器协同发压)

复制代码
JMeter Controller(控制台/报告生成,Port 1099)
       │ RMI
  ┌────┼────────────┐
  │    │            │
Slave1  Slave2     Slave3
800线程  800线程   800线程
  └─────┬────────────┘
        │ 共同发压
   被测服务(金融核心系统)

为什么单机 ~1000 并发封顶?

单台 JMeter 进程稳定并发约 800-1000 线程,超过后:

  • JVM 堆内存暴涨(每线程 1MB 栈空间)
  • RMI 通信开销成倍增加
  • JMeter 自身先 OOM / CPU 打满,成为瓶颈而非被测服务

金融项目推荐规格: 3-5 台 Slave × 800 线程 = 2400-4000 总并发,覆盖绝大多数场景


2. JMeter vs wrk / Locust / k6 / Gatling

工具 语言 协议 上手 报告 金融项目评价
JMeter Java HTTP/Dubbo(插件)/gRPC(插件) 基础 全协议,体系成熟,GUI 性能差
wrk C 仅 HTTP 极弱 性能极高,适合 HTTP 基准测试
Locust Python HTTP/gRPC 分布式强,GIL 限制单机性能
k6 Go HTTP/gRPC/GraphQL JS 脚本,DevOps 友好
Gatling Scala HTTP/Dubbo 最强 报告最专业,Scala 门槛高

金融项目首选:JMeter(HTTP 主链路) + wrk(HTTP 基准线) + SkyWalking(链路分析)


3. JMeter + SkyWalking 联动压测

核心分工:JMeter 发请求记 RT,SkyWalking 定位根因

复制代码
JMeter 发压 → Java Agent 自动埋点 → SkyWalking OAP → UI 实时拓扑/链路

实操四步:

  1. 被测服务挂载 SkyWalking Agent(-javaagent
  2. JMeter 压测请求加标签 Header:X-Biz-Scene=load-test
  3. SkyWalking UI 实时看拓扑图(哪个节点变红)+ Trace 筛选 load-test
  4. SkyWalking 链路详情直接定位慢节点(如:bank-gateway 1800ms,MySQL 50ms)

黄金法则: JMeter 告诉你"慢了",SkyWalking 告诉你"哪里慢了、为什么慢"