30 秒压测跑出 9000 QPS,全程无错误,被判为通过。上线后每小时第 12 分钟开始 Full GC,每次 1.8 秒,接口超时成片出现。乍看像缓存或者权限的锅,追下去往往不是。

java -Xlog:gc*:file=/tmp/gc.log:time,uptime -jar app.jar
jstat -gcutil 1 5000 120

追下去是这么回事:短时压测看不到对象晋升和老年代增长,30 秒连一次 Young GC 都没跑满。内存泄漏和缓存堆积要十几分钟才显形。压测期间也没开 GC 日志,事后没有证据可查。

「压测时长不足」相关的日志我一般连着看前后五分钟,单看一条报错经常判断不出是哪一步失败。接口问题先分清是没发出去、发出去了没收到,还是收到了处理失败。

偶发问题先统计频率,一小时几次和一天一次,查法完全不同。

具体做法是,压测时长至少覆盖一个完整的 GC 周期 建议 30 分钟以上;开启 GC 日志 记录每次停顿和回收量;观察老年代使用率是否持续上涨不回落;按峰值持续 10 分钟设计 别用瞬时峰值定容量。

验收就看一点,30 分钟压测里老年代使用率稳定,没有 Full GC,P99 不随时长上升。

作者 9823189