🎈

Fly.ioの無料枠へSpring Bootアプリケーションをデプロイする

2023/01/29に公開

概要

Fly.ioの無料枠で使えるVM(CPU 1 shared、RAM 256MB)へSpring Bootアプリケーションをデプロイしたのでポイントをメモしておきます。

Cloud Native Buildpacksでビルドしたコンテナイメージをデプロイする

コンテナイメージのビルドにはCloud Native Buildpacksを使えます。

https://fly.io/docs/reference/builders/

fly.tomlへ次のように記述します。

[build]
  builder = "paketobuildpacks/builder:base"

[build.args]
  BP_JVM_VERSION = "17"
  BPE_BPL_JVM_THREAD_COUNT = "30"
  BPE_DELIM_JAVA_TOOL_OPTIONS = " "
  BPE_APPEND_JAVA_TOOL_OPTIONS = "-XX:ReservedCodeCacheSize=30M -Xss256k"
  BPE_SERVER_TOMCAT_THREADS_MAX = "10"

BP_JVM_VERSIONでJavaバージョンを設定しています。
詳細はbellsoft-libericaのGitHubリポジトリを参照してください。

https://github.com/paketo-buildpacks/bellsoft-liberica

BPE_から始まる変数でコンテナイメージへ埋め込む環境変数を設定しています。
詳細はenvironment-variablesのGitHubリポジトリを参照してください。
設定している環境変数の内容については後述します。

https://github.com/paketo-buildpacks/environment-variables

設定している環境変数の内容について(メモリー計算)

VMのメモリーが小さいため何も設定しないでいるとSpring Bootアプリケーションは動いてくれません。

Javaのメモリー計算はJavaビルドパックのリファレンスが参考になります。

https://paketo.io/docs/reference/java-reference/#memory-calculator

コードキャッシュ、スレッドスタックのサイズだけで合計490MBが必要になるため、これらを削って非ヒープを100MB台まで絞ります。

コードキャッシュを削る

コードキャッシュはデフォルト240MBです。

まずはNative Memory Trackingでどれぐらいコードキャッシュを使っているか確認します。
ローカルで-XX:NativeMemoryTracking=summaryを付けてアプリケーションを起動し、jcmdVM.native_memoryを見てみます。

 -                      Code (reserved=249004KB, committed=21576KB)
                             (malloc=1320KB #7501)
                             (mmap: reserved=247684KB, committed=20256KB)

コードキャッシュで約21MB使用していました。
余裕を持たせて30MB確保しておきます(-XX:ReservedCodeCacheSize=30M)。

スレッドスタックを削る

次にスレッドスタックを削ります。
1スレッドあたりのスレッドスタックがデフォルトで1MB、それからコンテナイメージに設定されたメモリー計算用のスレッド数が250なので、1MB * 250 = 250MBとなります。

250という数はSpring Bootの組み込みTomcatの最大スレッド数(200)と、それ以外のスレッド数(50)を合わせたものです。
今回のアプリケーションは主に私しか使わないのでTomcatのスレッドは10もあれば十分です(BPE_SERVER_TOMCAT_THREADS_MAX = "10")。

またVMのメモリーが256MBと小さいためG1GCは使われずシリアルGCになり、GCに使用されるスレッドがかなり少なくなることも考慮し、全体で30スレッドを見込んでおくことにしました(BPE_BPL_JVM_THREAD_COUNT = "30")。

さらに1スレッドあたりのスレッドスタックも1MBから256KBへ減らしています(-Xss256k)。
少しずつ値を変更しつつ計測したところ最低限170KBでも一通り動作したので、余裕を持って256KBとしました。
これでスレッドスタックに割くメモリーは256KB * 30 = 7680KB = 7.68MBとなります。

ダイレクトメモリーとメタスペースを含めても非ヒープを130MB程度に抑えられました。

おわりに

以上のようにメモリーのチューニングをする必要はありましたが、無事にFly.ioの無料枠でSpring Bootアプリケーションを動かせられました。

Discussion