1. 概述

Java Flight Recorder (JFR) 是JVM内置的强大监控工具,用于捕获诊断事件来分析应用性能。在Quarkus中集成JFR后,不仅能获取标准JVM事件,还能利用Quarkus特有的扩展事件,实现更精细的监控。

本文将演示如何在Quarkus项目中配置JFR、创建自定义事件,并通过分析数据快速定位性能瓶颈。

2. Maven依赖

启用JFR功能需添加quarkus-jfr扩展。该扩展将JFR与Quarkus深度集成,提供专属监控事件:

<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-jfr</artifactId>
    <version>3.17.3</version>
</dependency>

3. 项目配置

3.1 创建REST接口

先创建一个简单的REST接口作为监控目标:

@Path("/hello")
public class JfrResource {
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "hello";
    }
}

3.2 启动飞行记录器

⚠️ 关键步骤:需通过JVM参数启用JFR自动录制。开发时可在application.properties中配置,或直接在启动命令中添加:

quarkus dev -Djvm.args="-XX:StartFlightRecording=name=quarkus,dumponexit=true,filename=myrecording.jfr"

此配置会:

  • 应用启动时自动开始录制
  • 程序退出时将记录保存到myrecording.jfr

4. 保存JFR记录

默认情况下,JFR会在应用终止时自动保存记录。也可手动触发:

  1. 终端按CTRL+C优雅退出
  2. 使用jcmd命令强制转储:
jcmd <PID> JFR.dump name=quarkus filename=myrecording.jfr

获取PID技巧:直接运行jcmd命令会列出所有Java进程及其ID

5. 分析JFR记录文件

5.1 使用JFR命令行工具

适合快速查看关键事件:

jfr print myrecording.jfr

输出示例:

Event: io.quarkus.HttpRequest
  Method: GET
  Path: /hello
  ResponseCode: 200
  Duration: 3ms

Event: jdk.GarbageCollection
  StartTime: 2024-11-10T14:23:45.123Z
  Duration: 5ms
  Cause: System.gc()

🔍 过滤特定事件

jfr print --categories "quarkus" myrecording.jfr

5.2 使用JDK Mission Control (JMC)

JMC提供图形化界面进行深度分析:

  1. 启动JMC(终端输入jmc或通过GUI)
  2. 通过File > Open File加载记录文件

JMC分析界面

核心功能:

  • 事件浏览器:查看HTTP请求、内存使用、GC等事件
  • Quarkus专属事件:如io.quarkus.HttpRequest分类展示
  • 时间轴视图:直观识别性能瓶颈和事件关联

6. 添加自定义事件

除内置事件外,可创建自定义事件监控业务逻辑:

@Name("com.baeldung.DatabaseQueryEvent")
public class DatabaseQueryEvent extends Event {
    private final String query;
    private final long executionTime;

    public DatabaseQueryEvent(String query, long executionTime) {
        this.query = query;
        this.executionTime = executionTime;
    }

    // Getter方法
    public String getQuery() { return query; }
    public long getExecutionTime() { return executionTime; }
}

在业务代码中触发记录:

DatabaseQueryEvent event = new DatabaseQueryEvent("SELECT * FROM users", 15);
event.commit();

查看自定义事件:

jfr print --events DatabaseQueryEvent myrecording.jfr

7. 总结

Quarkus + JFR的组合拳为性能优化提供了强力支持:

  • ✅ 通过内置事件快速诊断JVM层问题
  • ✅ 利用Quarkus专属事件监控框架行为
  • ✅ 自定义事件实现业务级精准监控
  • ✅ 命令行工具适合快速排查,JMC适合深度分析

这套方案特别适合需要持续监控生产环境性能的团队,能显著缩短问题定位时间。


原始标题:Using Java Flight Recorder (JFR) in Quarkus | Baeldung