Quarkusに統合された JDK Flight Recorder

Red Hat で Java や Quarkus を担当している伊藤ちひろです。

今回は、Quarkus で将来的に使えるようになる新機能を紹介します。

QuarkusはJDK Flight Recorderをquarkus-jfrとして統合しました。 JFRは、さまざまな情報をイベントとして記録します。

この統合により、各スレッドで発生したイベントを時系列に見られます。 この図では、Quarkusの処理の中核であるvert.x-eventloop-threadがいつ何を処理しているのかを表しています。 スレッド名右側の四角は、左から右に時間が流れています。 緑はスレッドに何もイベントがありません。 オレンジは REST の処理をしていることを示しています。

quarkus-jfrは、このようにJFRに独自のイベントを提供し、アプリケーションの問題解決を助けます。 quarkus-jfrはJVMモードだけではなく、ネイティブモードでも使用できます。

quarkus-jfrの詳細はこちらをご覧ください。

Using JDK Flight Recorder - main - Quarkus

本記事では、その機能を抜粋して紹介します。

quarkus-jfrは、リクエストIDを提供します。 リクエストIDは、quarkus-jfrが提供する全てのイベントはこれを活用します。 このリクエストIDは、同一HTTPリクエスト内で記録される全てのイベントで同じIDが使用されます。 これは、さまざまな箇所で記録されるイベントを関連付け、問題箇所の切り分けが容易になります。 たとえば、アプリケーションは提供するREST APIの中でデータストアへアクセスするとします。 このとき、「REST APIの処理」と「その処理内で行われるデータストアへのアクセス」は、同一のリクエストIDを持ち、それぞれで作成されるイベントは関連付けられます。 もし、REST APIの処理時間が長期化した場合に、みなさんはその処理内で行われたデータストアへのアクセスが長期化したせいでREST APIの処理時間が長期化したのかどうかを簡単に確認できます。

quarkus-jfrはOpenTelemetryとも連携します。 Quarkusが OpenTelemetry を使用している場合、quarkus-jfrは Opentelemetry の Trace IDとSpan IDをリクエストIDとして使用します。 これにより、OpenTelemetry でシステム全体を確認し、問題があった場合に、特定のQuarkusアプリケーションへのドリルダウンを容易にします。

[NOTE] 今はREST APIのイベントのみを記録します。

quarkus-jfr はQuarkusの標準のエクステンションです。 そのため、依存関係を追加するだけで使用できます。

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

アプリケーションの修正は必要ありません。 依存関係を追加するだけで、自動的に情報を記録します。

Quarkusは、その下で動いているJava仮想マシンでJFRを起動しなければなりません。 JFRを起動する方法はさまざまあります。 ここでは、Javaアプリケーションの起動時にJFRを起動する方法を紹介します。 起動時にJFRも起動するには、JVM起動引数に-XX:StartFlightRecordingを追加します。 JFRが初めての場合は以下のように設定すると良いでしょう。

export JAVA_OPTS=-XX:StartFlightRecording=name=quarkus,dumponexit=true,filename=myrecording.jfr

上のコマンドを実行したら、次に、アプリケーションを起動します。 mvnjavaを使う方法はそれぞれ以下のようになります。 どちらかを実行すればアプリケーションが JFR の記録を開始して起動します。

mvn -Djvm.args="${JAVA_OPTS}" quarkus:dev
java ${JAVA_OPTS} -jar quarkus-app.jar

あとは、これまで同様にアプリケーションを使うだけです。

先ほどの起動引数では、Javaアプリケーション終了時にJFRの情報をmyrecording.jfrというファイルにダンプするようになっています。 このダンプファイルは、専用のビューアであるJDK Mission Control (JMC) や、jfrコマンドで開けます。

JMCでダンプファイルを開き、スレッドの情報を見るビューを開いてみましょう。 そうすると、最初に紹介した図が見られるようになります。

気になるイベントが見つかれば、そのイベントのTrace IDやSpan IDにフォーカスすることで、同一のIDを持つイベントだけが表示されます。 これによって、同一リクエスト内でどのような処理がどのくらい時間を要しているかを簡単に特定できます。

さいごに

quarkus-jfrは開発中のリポジトリに統合されました。 先日 Quarkus 3.11 のタグ付けがされたことから、おそらく Quarkus 3.12 で使用できるようになるでしょう。 Red Hat が提供する Red Hat build of Quarkus では、新たな LTS が登場すると使用できると思いますが、サポートされるかどうかは今のところ分かりません。 新たな情報が分かり次第この場で共有させていただきます。

興味のある方は開発中のリポジトリをクローンすることで今すぐ試せますので、ぜひリポジトリをクローンしてみて下さい。

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。