BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース Quarkus 1.11の開発モードに新機能 "State Preserving Reload” が追加

Quarkus 1.11の開発モードに新機能 "State Preserving Reload” が追加

原文(投稿日:2021/04/13)へのリンク

今年初め、Quarkusの開発モードに新機能 "state preserving reload" が追加された。この機能はQuarkus 1.11以降で提供されていたもので、ほぼ瞬時の再ロード時間と、以前の状態の保持を可能にする。再ロード時間と終了時間の大幅な短縮と合わせて、Quarkusでは、開発モードを使用したアプリケーション開発の効率向上をうたっている。開発モードは、ブラウザの表示更新時にアプリケーション内のコード変更の再コンパイルと再ロードを実行する、ホット再デプロイメカニズムである。クラウド時代を反映して、リモート開発モードも提供されており、リモートコンテナ上でも使用することができる。

Quarkusの開発モードに関する理解を深めるべく、Red HatのシニアプリンシパルソフトウェアエンジニアであるStuart Douglas氏に話を聞いた。


InfoQ: InfoQ読者の質問に回答する時間を頂いて、ありがとうございます。Red Hatにおける現在の役割について教えてください、つまり、日々の業務はどのようなものでしょうか?

Stuart Douglas:

コアやHTTPレイヤを中心に、フルタイムでQuarkusに従事しています。日々の作業は、バグ修正と新機能の開発という、ほぼ一般的な組み合わせです。オーストラリアで開発しているのですが、このタイムゾーンにいるのは私だけなので、ミーティングはいつも深夜になります。

InfoQ: Quarkusの開発モードのホットデプロイはとても便利な機能で、特に再デプロイに時間の必要なアプリケーションで有用なのですが、この機能を有効にするにはどうすればよいのでしょうか?

Douglas:

開発モードはQuarkusのコアの一部なので、すべてのQuarkusアプリで使用することができます。`mvn quarkus:dev`または`gradle quarkusDev`を実行することでローンチが可能です。Quarkusを使うアプリであれば、すべて開発モードを使用できるはずです。さらに、IDEから実行するmainクラスがあれば、その環境でも同じように機能します。現在はJBangでもサポートされています。

InfoQ: この機能を使用する上で、何か推奨することはありますか?複数のコード変更のあるインスタンスには、どのように対処していますか?また、使用に際して、何か制限はあるのでしょうか?

Douglas:

ブラウザをリフレッシュするまで、アプリケーションは再ロードされません。ですから、ファイルの変更が複数あったとしても、リフレッシュするまではコンパイルや再ロードは行われないのです。現実的な唯一の制限は、Quarkusエクステンション自体をライブで再ロードすることはできない、ということです。ですから、Quarkusエクステンションを含むプロジェクトは、部分的に再ロードが不可能になります(ただしこれは特殊なケースです。というのは、プロジェクトにエクステンションを含めることは、通常は推奨してないからです)。

InfoQ: この機能がどのように実装されているのか、内部について説明して頂けますか?

Douglas:

この機能にはいくつかのパーツがあります。Quarkusはローンチ時にローカルプロジェクトの構造を参照して、プロジェクトのレイアウトや、プロジェクト内の全ファイルの配置先について理解します。プロジェクト内にあるすべてのコードは、廃棄可能(disposable)なClassLoader内にロードされます。一方で、Quarkus自体を含むすべてのライブラリは、これとは別のClassLoaderにロードされます。

HTTP要求がQuarkusに届くと(ブラウザのリフレッシュを実行した場合など)、非常に早い段階でこの要求をインターセプトして、更新をチェックするためにすべてのソースファイルをスキャンします。更新されたファイルがあれば、それらを再コンパイルして、廃棄可能なClassLoaderをドロップした上で、新たなClassLoaderでQuarkusを再起動し、更新されたバージョンのアプリケーションでインターセプトした要求の処理を続行します。これによって、常に最新バージョンのアプリケーションが表示されるようになるのです。リスタートのトリガとしてブラウザのリフレッシュを使っている、ということになります。

InfoQ: ホットデプロイ機能を開発する上で、最も大きな技術的課題は何でしたか?

Douglas:

IDEから実行可能にすることが、非常に難しい点でした。Quarkusは最終的にアプリケーションになるランタイムパートと、開発モードの全機能を含むデプロイメントパートという2つの部分と、最終的なアプリケーションを生成するコードで構成されています。プロジェクトのクラスパスには通常、この内のランタイムパートしかないので、関連するクラスやクラスパスのない状態で開発モードをブートストラップしようとすると、いくつかのトリックが必要になりました。

InfoQ: Red Hatの傑出したエンジニアでJBangの作者でもあるMax Rydahl Andersen氏のツイートによると、Quarkus 1.11以降の開発者モードには、コード変更をJVM Instrumentationに適用可能かどうかを検出する機能が加えられている、ということですが、この機能追加にはどのようなメリットがあるのでしょうか?この機能はデフォルトで有効なのですか?

Douglas:

メリットはおもに2つあります。ひとつはアプリケーションを再起動する必要がない、ということです。Instrumentationベースの再起動は非常に高速(ほぼ瞬時)なので、再ロードに必要な時間は変更のコンパイル時間のみになります。もうひとつのメリットは、アプリケーションの状態を維持できることです。例えばHibernateでは、データベースを再生成しないことで時間を短縮できます。

この機能はデフォルトで有効でしたが、Quarkus 1.13.1ではこれを変更して、デフォルトではオフになっています。スタートアップ時に実行される(または、Singletonが生成された時に1回のみ実行される)コードにおいて、混乱を引き起こす可能性があるため、このように変更しました。アプリケーションが再起動しないので、変更が即時有効にならないためです。Quarkus 2.0ではもっと簡単に、実行時に(おそらくDev UI経由で)オン・オフできる方法を提供したいと思っていますので、希望するモードを選択したり、必要に応じてボタンひとつで切り替えることが可能になるでしょう。

InfoQ: 差し支えなければ、開発モードのこの新機能を実装した方法について、詳しく説明して頂けますか?現在確認されている制限は何かありますか?

Douglas:

Quarkusが開発モードで起動すると、Maven/GradleプラグインがJavaAgentをコマンドラインに追加して、java.lang.instrument.Instrumentationにアクセスできるようにします。これによってクラスの修正が可能になるのです。クラスのコンパイルが完了すると、新たなクラスが旧バージョンとまったく同じシグネチャを持っていること(新たなメソッドがないこと、アノテーションがすべて同じであること、変更されたのは基本的にメソッドの内容だけであること)のチェックを行います。このチェックにパスすると、Quarkusを再起動せずに、Instrumentation APIを使ってクラスを置き換えます。

Instrumentationが使用できるのは、クラスのシグネチャが変更されていない場合に限ります。

InfoQ: JRebelなど同様のツールに対して、ホットデプロイ機能のユニークな部分は何ですか?

Douglas:

大きな違いは、プロジェクトに統合されていることです。ですから、誰でもセットアップ不要で使用することができるのです。もうひとつの大きな違いは、外部ツールに頼らずに、コンパイルを含むエクスペリエンス全体を完全にコントロールしている点です。HTTPベースの(タイマを使わない)変更検出アプローチによって、開発者は常に、最新の結果を目にすることが可能になっています。

アプリケーションの高速な再ロードだけでなく、開発中の効率やフィードバックの向上にも重点を置くことによって、Quarkusは、Javaのような成熟した言語とそのエコシステムを利用するメリットと、PythonやJavaScriptのようなスクリプト言語に見られるような高速なフィードバックというメリットを両立させようとしている。

この記事に星をつける

おすすめ度
スタイル

BT