BellSoftは、チェックポイントでの調整されたリストア(CRaC)を備えたOpenJDKのダウンストリーム・ディストリビューションであるLiberica JDKのバージョン17と21をリリースした。この機能により、開発者は任意の時点(チェックポイント)で実行中のアプリケーションのスナップショットを作成できる。このスナップショットは、アプリケーションの状態を復元することにより、ミリ秒以内でアプリケーションを起動するために使用される。
CRaCは、Linuxの機能であるCRIU(Checkpoint and Restore in Userspaceをベースにしており、Linuxオペレーティングシステムを実行するx86_64およびAArch64CPUアーキテクチャでのみビルドが可能である。CRIUはチェックポイントとリストアの機能を提供し、Dockerや Podmanなど様々なソリューションで利用されている。
CRaCは、Javaヒープ、JITコンパイルされたコード、ネイティブ・メモリー、設定など、実行中のアプリケーションの状態を保存する。開発者は、保存された状態にパスワードのような機密データが存在しないことを確認する必要がある。初期化時に、JavaRandom
クラスによってシードが生成される。これは、スナップショット・リストア後の数値が予測可能であることを意味する。リストア後のランダム性を実現するには、afterRestore()
メソッドで新しいシードを作成する必要がある。JavaのSecureRandom
クラスを使用することで、スナップショットの前にシードをクリーンにしてランダム操作をロックし、その後 afterRestore()
メソッドでロックを解除できるさらに優れたソリューションになる。
調整されたチェックポイントとリストアは、アプリケーションが一時停止と再起動の事実を認識していることを確認する。プロセスの信頼性を高めるために、ネットワーク接続と開いているファイル演算子が閉じられていることを確認する。また、このプロセスによって、例えばユーザー・データの保存中などでまだ準備ができていない場合に、アプリケーションがチェックポイントをキャンセルできるようになる。
以下のコマンドを使用すると、MyApplication
を起動し、スナップショットが作成されるたびに、最終的にJVMデータを含むことになるcheckpoint-dataディレクトリを指定できる。
java -XX:CRaCCheckpointTo=checkpoint-data MyApplication
次に、jcmdコマンドを使ってスナップショットを作成する。
jcmd MyApplication JDK.checkpoint
その後、checkpoint-data ディレクトリのスナップショットの状態を復元することで、アプリケーションを起動できる。
java -XX:CRaCRestoreFrom=checkpoint-data
アプリケーションの高速起動を可能にする他のソリューション、例えばGraalVMで使用されるAhead of Time(AOT)コンパイルや、Quarkusで使用されるApplication Class Data Sharing(AppCDS)も、高速起動を提供している。しかし、これらのソリューションは、ランタイム中のJITコンパイラによる更なる最適化をサポートしていない。
BellSoftは、CRaCを主に次のような特徴を持つアプリケーションに使用するようアドバイスしている。 短時間の実行、低いCPU制限、複製、頻繁な再起動
CRaCはもともとAzulによって開発され、OpenJDKプロジェクトの1つとなっている。Azulは、OpenJDKのダウンストリーム・ディストリビューションであるZuluにもCRaCを組み込んでいる。CRaCは主流になりつつあり、Spring Boot、Quarkus、Micronaut、AWS Lambda SnapStartなどのツールでサポートされている。
通常のJavaアプリケーションとSpring BootアプリケーションでCRaCを使う方法についての詳細は、Bellsoftのパフォーマンス・アーキテクトであるDmitry Chuyko氏が書いたブログ「How to use CRaC with Javaapplications」で見ることができる。