Bootiful Spring Boot
このセッションではKeynoteにも登壇したJosh Long氏がSpring Bootの機能の紹介をライブコーディングを通して披露しました。Josh Long氏は多くのイベントで同タイトルの講演を行っていますが、内容は都度アップデートされています。
今回使用されたSpring Bootのバージョンは3.3.3、Javaのバージョンは21です。
まず1つ目に紹介されたのはSpring Modulithを利用したモジュラモノリスシステムの構築です。モジュラモノリスとはソフトウェアアーキテクチャの一種で、1つのアプリ内で機能をモジュールという単位で分割することにより、モノリスの特徴にマイクロサービスのようなサービス分割を導入します。
モジュール間のやり取りにはイベントの出版と購読(Pub-Sub)を利用します。イベントには複数の考え方が存在することをMartin Fowler氏のWhat do you mean by “Event-Driven”?の記事を通して紹介されました。
デモとしてモジュール間のイベント通知を実装し、Spring Modulithの機能としては以下が紹介されました。
- @EventListnerで同期、@ApplicationModuleListnerで非同期のイベント購読が可能
- 非同期の場合はプロパティファイルからイベントログの永続化、中断したイベント購読がアプリ再起動時に再講読される設定が可能
- モジュール構造の検証テスト
- ソースコードからasciidoc形式のドキュメント生成
2つ目に紹介されたのはSpring AIを利用したチャット機能の実装です。LLMに対してSpring AIでRAG(Retrieval-Augmented Generation)を構成することで、ローカルのデータベースにある情報を参照可能なAIチャットサービスのデモをしました。このデモではチャットモデルとしてOpenAI、ベクターデータベースとしてPGvectorが利用されていました。Spring AIで対応可能な製品を知りたい場合は公式ドキュメントをご参照ください。
3つ目に紹介されたのは仮想スレッド(VirtualThreads)を利用したパフォーマンスの改善です。仮想スレッドはブロッキングI/Oで発生する待機中のスレッドを効率化することで高スループットを実現するJavaの軽量スレッドであり、Java 21でリリースされ、Spring Boot 3.2からサポートされました。Spring Bootでは、プロパティファイルの設定によって仮想スレッドを有効化することができます。デモでは仮想スレッドを有効化した場合と無効な場合で性能検証が行われ、仮想スレッドの導入により約2倍のスループットを発揮することを示しました。
最後にアプリケーションをより高速、低メモリで実行するためにGraalVMによるNative Imageビルドを実演してセッションは締めくくられました。
本セッションで扱われたデモコードはJosh Long氏のGitHubリポジトリから参照可能です。
Efficient Containers with Spring Boot 3, Java 21 And CDS
引き続きキーノートのスピーカーのセッションを紹介します。このセッションではBroadcom社のSpring FrameworkのコアコミッターでもあるSébastien Deleuze氏からSpring Boot 3、Java 21、CDS(Class Data Sharing)を使ったコンテナ効率化の方法が紹介されました。
前提として、なぜランタイム効率を気にする必要があるのかを3つの観点から説明されました。
- コスト削減:(クラウド上で)従量制によるリソース使用料をより安価にする
- 持続可能性:CPU効率を改善することでメモリ消費、電力消費を低減する
- コンテナの最適化:JVMをコンテナで起動する際のメモリ消費、ウォームアップ時間を改善する
Spring Boot 3のランタイムを効率化する機能に着目すると、GraalVM、Spring AOT、Virtual Threads、Project CRaC、CDSがあります。GraalVM、CRaC、CDSについてどれを採用するべきかについては、条件によって変化しますが、一般的に言える比較として下図内の表が示されました。
GraalVMは100msレベルの高速起動や高いセキュリティなど強いメリットを持つ一方、非常に遅いコンパイル時間や、GraalVMが対応していないライブラリを利用する場合は事前に動的に読み込むクラスを設定する必要がある等のデメリットがあります。CRaCはGraalVM同様の高速起動が可能なメリットを持つ一方、3つの大きなデメリットが存在します。
-
複雑なライフサイクル
- CRaCで作成したチェックポイントの状態から復元する際はファイルハンドルとソケットを再作成する必要があります。
-
セキュリティ上の問題
- メモリのスナップショットをディスク上にシリアル化された状態で配置することになるため、メモリ内に含まれる機密情報が漏れる可能性があります。
- サポートOSがLinux限定
CDSは大きな制約やデメリットは無く、CDSアーカイブを作成する手間を加えるだけで1.5倍~2倍程度の起動時間の高速化が可能になります。
次にSpring BootでCDSを利用するための方法が説明されましたが、紙面の都合上、詳細な手順については Spring Blogの同氏の解説をご参照ください。
これまでに紹介があった機能を導入するデモとして、サンプルアプリをSpring Boot 2(Java 8)からSpring Boot 3(Java 21)へアップグレードしてCDSなどの最適化を盛り込むデモが披露されました。コードは同氏のGitHubリポジトリにて公開されており、コミット履歴から段階的に導入する手順を追うことができます。最適化の効果として起動時間、メモリ消費量、JDBCスループットの計測結果が示され、いずれも一定の効果を発揮していることが見て取れました。
図内でも記載がある通り、Spring Boot 3.4(Spring Framework 6.2)ではWebJarsに関する問題(#27619)が解消されることでパフォーマンスが改善される予定であることが補足されました。
最後に、Java PlatformチームとSpringチームはProject Leydenで更なる最適化(上述したサンプルアプリで300ms以下の起動時間)を実現するために今後も連携していくと述べ、セッションを締めくくりました。