采集JFR时SpringBoot应用TPS骤降:命令是否有误?JFR是否影响性能?
问题解答
1. 你的JFR命令是否存在问题?
你的JFR命令语法上没有错误,但选择的采集配置是导致性能骤降的核心原因:
/opt/drutt/local/jdk1.8.0_112/bin/jcmd JFR.start settings=profile duration=1m filename=/tmp/my_file_1.jfr
这里使用的settings=profile是JFR的深度分析预设,它会开启大量细粒度的事件采集(比如高频方法采样、对象分配追踪、锁竞争细节等),这类配置更适合低负载场景下的问题排查,而非500TPS的高负载生产环境运行时。
2. JFR是否会导致性能下降?
JFR的设计目标是低开销监控,但开销大小完全取决于你选择的采集配置:
- 若使用
settings=default(默认预设),通常性能开销在1%以内,几乎不会影响日常500TPS的稳定运行; - 而
settings=profile这类深度分析配置,在高负载场景下可能带来5%-20%甚至更高的性能损耗——你遇到的TPS从500降到100以下的情况,就是因为高TPS下大量细粒度事件的采集消耗了额外的CPU和内存资源,挤占了应用本身的运行资源。
另外补充一点:你使用的JDK版本是1.8.0_112,这是JFR刚集成到Oracle JDK的早期版本,后续JDK 11及以上版本对JFR的性能做了大量优化,开销会显著降低,如果条件允许,升级JDK也能缓解这类问题。
优化建议
- 优先使用
settings=default做日常监控,既能获取关键运行数据,又不会影响性能; - 若必须做深度分析,可自定义采集配置,比如降低方法采样频率(例如添加
sample.threshold=20ms参数,减少采样次数),或关闭非必要的事件; - 尽量在低峰时段执行深度采集,避免影响业务高峰的TPS。
内容的提问来源于stack exchange,提问作者Ravish




