Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Running Kotlin + Quarkus with Lambda

Avatar for Nealle Nealle
October 14, 2026

Running Kotlin + Quarkus with Lambda

Server-Side Kotlin Meetup vol.20 登壇資料
https://server-side-kotlin-meetup.connpass.com/event/405098/

Avatar for Nealle

Nealle

October 14, 2026

More Decks by Nealle

Other Decks in Technology

Transcript

  1. NEALLE Kotlin + Quarkus を Lambda SnapStart で動かす - 仕組みと事前ウォームアップ

    2026.10.14 Server-Side Kotlin Meetup vol.20 株式会社ニーリー 宮後 啓介 @miya10kei 1
  2. 自己紹介 Keisuke Miyaushiro 宮後 啓介 株式会社ニーリー プラットフォーム本部 プロダクトAI開発 リーダー 2023年にニーリーにジョイン

    SREリードとしてサービスの信頼性やアジリティ向上の施策を実施。 2025年よりプロダクト/事業部門での生成AI活用を推進するチームを立 ち上げ。 現在は新規プロダクト開発とCSS業務の効率化を担当 @miya10kei 2
  3. SnapStartの仕組み - 背景 外部SaaSからのWebhookを受けるAPIに「Kotlin + Quarkus on Lambda」を利用中! 【Lambdaを採用した理由】 1.

    2. 3. リクエスト数が時間帯で大きく変動する 急激なスパイクが想定される Web APIと負荷特性・可用性要件が異なる → 常時稼働によるコストを抑えたい → 高速なスケールアウトが求められる → 分離して低コストで運用したい → LambdaにはCold Startという課題があるのでそこへのアプローチを紹介します! Kotlin + Quarkusを選択した経緯はこちらで紹介しています! 「どうして今サーバーサイドKotlinを選択したのか @ Server-Side Kotlin LT大会 vol.19」 6
  4. SnapStartの仕組み - LambdaでKotlinを動かす時の選択肢 - Cold Start 追加料金 アプリ側の対応 On-Demand 長い

    なし なし Provisioned Concurrency 確保分は発生しない あり なし SnapStart 短い なし 事前ウォームアップ GraalVM Native 最も短い なし Native Build対応 Cold Startによる遅延を抑えつつ、低コストで運用可能なSnapStartを選択! → 将来的にはGraalVM Nativeも視野に入れている 7
  5. SnapStartの仕組み - CRaC(Coordinated Restore at Checkpoint)CRaCはJVM の起動とウォームアップを短縮する OpenJDK プロジェクト →

    初期化済のイメージを事前作成し、復元して起動を高速化する仕組み 通常起動 起動のたび JVM起動 アプリ初期化 初回リクエスト処理 (クラスロード等で遅い) JVM起動 アプリ初期化 beforeCheckpoint() (保存直前のフック) afterRestore() (復元直後のフック) リクエスト処理 リクエスト処理 CRaC 事前に1回 起動のたび 復元 保存 イメージ 8
  6. SnapStartの仕組み - SnapStart SnapStart は Lambda の Cold Start を短縮する

    AWS の機能 → 初期化済の実行環境のスナップショットを事前作成し、復元して起動を高速化する仕組み Cold Startのたび バージョン発行時 実行環境(microVM) JVM起動 アプリ初期化 beforeCheckpoint() afterRestore() リクエスト処理 afterRestore() リクエスト処理 afterRestore() リクエスト処理 復元 保存 スナップショット 9
  7. SnapStartの仕組み - CRaCとSnapStartの関係 SnapStart は CRaC のフックの API だけを採用している →

    保存と復元の仕組みは Lambda 独自で、アプリは CRaC と同じ API でフックを書く アプリ フックの実装を登録 Resource / 共通API(org.crac) beforeCheckpoint() / afterRestore() フックを呼び出す CRaC対応JDK フック呼び元:JDK 保存対象 :JVMプロセス 保存手段 :CRIU • • Lambda SnapStart フック呼び元:Lambda Runtime 保存対象 :microVM 全体 保存手段 :Firecracker CRIU(Checkpoint/Restore In Userspace): 動作中の Linux プロセスの状態を保存し、そこから再開できるツール Firecracker: AWS が開発した軽量の仮想マシンモニター。Lambda の実行環境(microVM)を動かしている 10
  8. 事前ウォームアップ - 自前でのプリロードの手段 - Class Priming Invoke Priming 「META-INF/quarkus-preload-classes.txt」 に対象クラスを記述することでプリロード対

    象にする手法 beforeCheckpoint()で実際の処理を呼び出す ことでプリロードをする手法 実行経路全体がプリロードの対象になる 【例】 com.amazonaws.services.lambda.runtime.LambdaRuntimeInternal com.fasterxml.jackson.annotation.JsonAlias com.fasterxml.jackson.annotation.JsonFormat$Feature com.fasterxml.jackson.core.exc.InputCoercionException ・・・ 実行 クラスA クラスB クラスC クラスD ※ ライブラリ更新への追従を考慮し採用! 13
  9. 事前ウォームアップ - Invoke Primingの実装方法 @Startup // 起動時にインスタンスを作らないと、フックが登録されない @ApplicationScoped class HelloPriming

    : Resource { @PostConstruct fun init() { Core.getGlobalContext().register(this) // フックを登録する } // スナップショットを取る直前に呼ばれる override fun beforeCheckpoint(context: Context<out Resource>) { // ここでリクエスト処理を 1 回実行する = Invoke Priming } // 復元した直後に呼ばれる override fun afterRestore(context: Context<out Resource>) { // 復元のたびに必要な処理を書く(接続の張り直しなど) } } 14
  10. 事前ウォームアップ - Invoke Primingの実行対象 リクエストが通る以下の処理を、それぞれの方法でInvoke Primingの実行対象とした。 • • • •

    • • 署名検証 ◦ ダミー署名の検証 設定データの読み込み ◦ 固定のJSONデータをパース レスポンスの生成 ◦ 固定値での全要素の組み立て DBの読み取り ◦ 未登録キーでのデータ読み取り DBの書き込み ◦ 書き込みSQLの組み立て(DBへの書き込みまではしない) 外部HTTP送信 ◦ ダミー宛先へのHTTP呼び出し 15
  11. 事前ウォームアップ - 副作用への対処(DB/HTTP) 1.DB接続のライフサイクルをSnapStartのフックで制御することで対処 quarkus.datasource.jdbc.initial-size=0 quarkus.datasource.jdbc.min-size=0 # 起動時の接続作成をOFF # 接続の作り直しをOFF

    // スナップショットを取る直前に呼ばれる override fun beforeCheckpoint(context: Context<out Resource>) { dataSource.flush(AgroalDataSource.FlushMode.ALL) // 接続をフラッシュ } // 復元した直後に呼ばれる override fun afterRestore(context: Context<out Resource>) { dataSource.connection.use { it.isValid(1) } // 接続を張り直す } 2.HTTP接続はKeep AliveをOFFにすることで対処 quarkus.rest-client.webpush-priming.keep-alive-enabled=false 17
  12. まとめ • SnapStart は「起動済みの状態を保存して復元する」ことで Cold Start を短縮する ◦ • Quarkus

    が自動でプリロードするのは自作クラスまで ◦ • リクエスト処理で使うライブラリのクラスは、自前でのプリロードが必要 Invoke Priming なら、実行経路ごとプリロードできる ◦ • アプリからは CRaC の API(フック)で、保存の直前と復元の直後に処理を挟める クラス一覧の管理が不要で、ライブラリ更新にも追従できる Invoke Priming の副作用(接続がスナップショットに入る)への対処が必要 ◦ DB 接続は SnapStart のフックで制御、HTTP 接続は Keep Alive を OFF 18