同一份脚本两轮压测,第一轮 8000 QPS,第二轮 4200 QPS,服务端 CPU 一样。两轮都没开 GC 日志,只能看到 RT 从 110 毫秒涨到 240 毫秒。日志里能对上时间点,这种反而好排。

两轮之间唯一的变化是 JVM 堆从 4G 改成了 2G,但没有记录。堆变小后 Young GC 频率翻倍,STW 累积起来吞掉一半吞吐。没有 GC 日志就无法把吞吐下降归因到回收。这一点先确认清楚,后面就不用反复试。

java -Xlog:gc*:file=/tmp/gc_$(date +%s).log:time,uptime -Xms4g -Xmx4g -jar app.jar
grep -c 'Pause Young' /tmp/gc_*.log

「GC 日志缺失」改完先别急着全量,挑一台机器放半天,真有问题这段时间就能看出来。偶发问题先统计频率,一小时几次和一天一次,查法完全不同。

改完顺手把文档补一句,省得下次自己重新推一遍。监控和日志的时间要对上,时区不一致会多绕很大一圈。

处理上按这个顺序:压测启动参数里固定加 GC 日志输出到文件;记录每轮压测的 JVM 参数和堆大小;对比 GC 次数、停顿总时间和吞吐的关系;把参数和结果一起归档 保证可复现。

结果对不对很好判断,两轮压测的 GC 日志能对上吞吐差异,调整堆之后两轮 QPS 差在 5% 以内。

作者 9823189