JVM チェックポイントの復元

Spring Framework は、プロジェクト CRaC [GitHub] (英語) によって実装されたチェックポイント / 復元と統合されており、JVM を使用した Spring ベースの Java アプリケーションの起動時間とウォームアップ時間を短縮できるシステムを実装できるようになります。

この機能を使用するには、以下が必要です。

  • チェックポイント / 復元が有効な JVM (現時点では Linux のみ)。

  • クラスパス内に org.crac:crac [GitHub] (英語) ライブラリ (バージョン 1.4.0 以降がサポートされています) が存在すること。

  • -XX:CRaCCheckpointTo=PATH や -XX:CRaCRestoreFrom=PATH などの必須の java コマンドラインパラメーターを指定します。

チェックポイントがリクエストされたときに -XX:CRaCCheckpointTo=PATH によって指定されたパスに生成されるファイルには、実行中の JVM のメモリ表現が含まれており、これには機密データやその他の機密データが含まれる可能性があります。この機能の使用は、環境から取得される構成プロパティなど、JVM によって「認識される」値がそれらの CRaC ファイルに保存されることを前提として実行する必要があります。これらのファイルがどこでどのように生成、保存、アクセスされるかというセキュリティへの影響を慎重に評価する必要があります。

概念的には、チェックポイントとリストアは個々の Bean の Spring Lifecycle 契約と一致します。

実行中のアプリケーションのオンデマンドチェックポイント / 復元

チェックポイントは、たとえば jcmd application.jar JDK.checkpoint のようなコマンドを使用して、オンデマンドで作成できます。チェックポイントの作成前に、Spring は実行中のすべての Bean を停止し、Lifecycle.stop を実装することで必要に応じてリソースを閉じる機会をそれらの Bean に与えます。復元後、同じ Bean が再起動され、Lifecycle.start により、Bean は必要に応じてリソースを再度開くことができます。Spring に依存しないライブラリの場合、org.crac.Resource を実装し、関連するインスタンスを登録することで、カスタムチェックポイント / 復元の統合を提供できます。

実行中のアプリケーションのチェックポイント / 復元を利用するには、通常、ファイルやソケットなどのリソースの使用を適切に停止および開始し、アクティブなスレッドを停止するために、追加のライフサイクル管理が必要です。
たとえば @Scheduled(fixedRate = 5000) のようなアノテーションを使用して、固定レートでタスクのスケジュールを定義する場合、チェックポイントとリストアの間で実行されなかったすべての実行は、オンデマンドチェックポイント / リストアを使用して JVM がリストアされたときに実行されることに注意してください。この動作が望ましくない場合は、タスクの実行ごとに計算される固定遅延 (たとえば @Scheduled(fixedDelay = 5000) を使用) または cron 式を使用してタスクをスケジュールすることをお勧めします。
ウォームアップされた JVM 上にチェックポイントが作成された場合、復元された JVM も同様にウォームアップされ、すぐに最高のパフォーマンスが得られる可能性があります。この方法では通常、リモートサービスへのアクセスが必要となるため、ある程度のレベルのプラットフォーム統合が必要になります。

起動時の自動チェックポイント / 復元

-Dspring.context.checkpoint=onRefresh JVM システムプロパティが設定されている場合、LifecycleProcessor.onRefresh フェーズの起動時にチェックポイントが自動的に作成されます。このフェーズが完了すると、すべての非遅延初期化シングルトンがインスタンス化され、InitializingBean#afterPropertiesSet コールバックが呼び出されます。ただし、ライフサイクルは開始されておらず、ContextRefreshedEvent はまだ公開されていません。

テスト目的で、同様の動作をトリガーする -Dspring.context.exit=onRefresh JVM システムプロパティを利用することもできますが、チェックポイントを作成する代わりに、Project CraC 依存関係 /JVM または Linux を必要とせずに、同じライフサイクルフェーズで Spring アプリケーションを終了します。これは、Bean が開始されていないときに リモートサービスへの接続が必要かどうかを確認し、それを回避するために構成を調整する場合に便利です。

上で記述されていたように、特に CRaC ファイルがデプロイ可能なアーティファクト (コンテナーイメージなど) の一部として提供されるユースケースでは、JVM によって「認識される」機密データはすべて CRaC ファイル内に保存されるという前提で動作します。関連するセキュリティへの影響を慎重に評価します。
自動チェックポイント / 復元は、アプリケーションの起動を、アプリケーションコンテキストが開始しようとしているフェーズまで「早送り」する方法ですが、JVM を完全にウォームアップすることはできません。