16 性能分析、压测与诊断工具
性能问题不能靠“感觉有点慢”定位,也不能靠一张高 QPS 截图证明容量。一次可信实验需要两条相互校验的证据链:JMeter、k6、wrk、ab、hey 制造受控负载;JFR、JMC、VisualVM、JDK CLI、Arthas、async-profiler 和 Chrome Performance 解释负载落到系统后发生了什么。
工具能启动,只证明执行入口存在。容量结论还依赖业务模型、生产压测授权、停止条件、限流与扩缩容策略、值班接管、服务端观测和业务目标。架构、研发、测试、平台与运维必须在实验前签清目标、流量上限、数据处置和止损责任,不能让一个压测脚本替团队做风险决策。
先分清三个问题
一次性能实验必须依次回答:流量是否符合真实业务模型,发压端是否先到瓶颈,被测系统的哪一层出现了可重复的饱和或等待。只回答其中一个,结论都不完整。
并发数、连接数、虚拟用户数和请求到达率不是同一个概念。平均耗时也不能替代 P95、P99、错误率和吞吐。测试开始前先写清开放或闭环负载模型、预热阶段、稳态阶段、测试数据、最大流量、立即停止条件,以及压测机自身 CPU、网络、文件句柄和临时端口的观测方法。
阅读顺序
| 文章 | 先解决的问题 | 架构师继续判断 |
|---|---|---|
| JMeter | 用测试计划、线程组、断言和 CLI 报告跑通复杂协议测试 | 分布式 Engine、结果回传、数据分片和性能门禁 |
| k6 | 用代码定义场景、Check 和 Threshold | 到达率模型、Operator、Cloud 数据边界和 CI 分层 |
| wrk、ab 与 hey | 快速建立 HTTP 基线 | 闭环偏差、协议边界和发压端饱和 |
| JFR、JMC 与 VisualVM | 录制并查看 JVM 运行证据 | 开销、事件选择、基线比较和敏感数据治理 |
| jcmd、jstack 与 jmap | 导出线程、类和堆证据 | attach 权限、停顿风险、容器 PID 和事故取证 |
| Arthas | 对限定类和方法做在线观察 | 字节码增强扰动、审计、恢复和生产边界 |
| async-profiler 与火焰图 | 生成 CPU、wall 或 alloc 火焰图 | 事件选择、采样偏差、容器权限和跨证据验证 |
| Chrome Performance 与 Web Vitals | 把页面长任务和体验指标接进性能实验 | 实验室与真实用户边界、前后端证据相关性 |
浏览器面板的具体采集操作见 Lighthouse 与 Performance 性能证据采集工具手册。采集完成后,还要用发布版本、实验阶段、请求 ID、Trace ID 和统一时钟把页面长任务、网络瀑布、服务端延迟、线程栈与资源饱和放回同一条时间线;否则前端截图和服务端压测报告仍是两组无法互证的材料。
一次可接受的性能实验
团队归档不能只有报告截图,至少要保存:被测版本和配置、目标环境、脚本版本、测试账号与数据策略、负载模型、预热和稳态时段、发压机规格与利用率、客户端原始结果、服务端指标、日志或 Trace、必要的 JVM/火焰图证据、停止条件是否触发、结论、限制和负责人。
性能结论必须带有效期。代码、JDK、依赖、实例规格、数据量、索引、网络拓扑或限流配置任一关键条件变化后,旧数字只能作为历史基线,不能继续承诺新系统容量。
共通安全底线
- 目标必须白名单化;默认只允许
localhost、专用测试域名和明确批准的环境。 - 写请求使用隔离租户和可清理数据,不能把压测数据混入真实订单、消息和审计报表。
- 从小流量阶梯升压,错误率、尾延迟、线程池、连接池、队列、数据库和业务告警任一越线立即停止。
- 认证信息不进入脚本、命令历史、JTL、Trace、heap dump、火焰图标签和 CI 日志。
- heap dump、线程栈、JFR、方法参数和浏览器 Trace 都可能含敏感数据,采集前确定审批、保存位置、访问者和删除时间。
- 线上诊断优先选择低扰动证据;任何 attach、字节码增强、heap dump 或长时间采样都要有 owner、期限、停止命令和回滚验证。
