このエントリは2020/11/02現在の情報に基づいています。将来の機能追加や変更に伴い、記載内容との乖離が発生する可能性があります。
先日までの一連のCloudEvents APIに関するエントリで、CloudEvents APIを使ったJAX-RSアプリケーションを作成、DockerコンテナにしてAzure App Serviceで動作させた。このJAX-RSアプリケーションはHelidonをベースにしており、Helidonのarchetypeでプロジェクトを生成すると、3種類のビルド方法をデフォルトで用意してくれる。このエントリでは、その3種類のビルド方式でのビルド成果物のサイズ、Dockerイメージのサイズを確認した。
前提条件、基本情報
今回対象にするJAX-RSアプリケーションは、先日のエントリで作成したCloudEventsを受け取るためのJAX-RSアプリケーション。以下のリポジトリの EventGridSubscriberがそれに該当する。
Azure Event Grid and CloudEvents
https://github.com/anishi1222/Azure-Event-Grid-and-CloudEvents/
Helidon
Helidonについては以下を参照。今回はHelidon MP 2.1.0を利用している。
Project Helidon
https://helidon.io
Helidonが用意するビルド方式
Helidonのarchetypeでプロジェクトを生成すると、以下の用途で利用できるpom.xml、Dockerfileが用意される。
通常 | jlink | Native | |
---|---|---|---|
ビルドコマンド | mvn package | mvn package -Pjlink-image | mvn package -Pnative-image |
Dockerfile | Dockerfile | Dockerfile.jlink [*1] | Dockerfile.native |
ビルド環境
Microsoft AzureのVirtual Machineを利用。Specは以下の通り。
Shape | Standard D16as_v4 |
vCPU数 | 16 |
RAM | 64 GiB |
OS | UbuntuServer 18.04 |
Java | GraalVM Community Edition 20.2.0 [*2] Azul Zulu 11.0.9+11 (Zulu: 11.43.21) |
ビルド時間計測条件
timeコマンドを利用して計測。
ビルド結果
通常 | jlink | native | |
---|---|---|---|
ビルド時間(平均)[sec] | 3.43 | 18.64 | 111.12 |
アーティファクトのサイズ [Byte] | 7,847 | 7,847 | 100,069,192 (95 MByte) |
コンテナイメージ
通常 | jlink | native | |
---|---|---|---|
ビルド時間(平均)[sec] | 300.91 | 320.06 | 435.82 |
イメージサイズ [MByte] | 223 | 199 | 96.8 |
作成に利用しているイメージ | maven (3.6-jdk-11) openjdk (11-jre-slim) | debian (stretch-slim) maven (3.6.3-jdk-11-slim) | helidon/jdk11-graalvm-maven (20.1.0) |
まとめ
わかっていることを確認しただけなので、正直まとめにもならないが、
- Native Imageを作成するには時間がかかる。Docker イメージ生成はもっと時間がかかる。
- Helidonの場合、Dockerイメージ作成のマルチステージビルドの中でソースコードをビルドしているため、
- Native Imageを包含するコンテナイメージ生成の場合、ビルドにあたってはメモリを潤沢に使えるようにしておく必要がある(16GBのLaptopではMaven実行中にHeapがOut of Memoryになってしまった)。
- jlinkを使ったイメージと通常のイメージの生成時間の差は、jlinkによるカスタムランタイム生成のオーバーヘッドがほぼそのまま残る。
- Native Imageを包含するイメージ生成時間でも同様の傾向が見られるが、jlinkの場合に比べてオーバーヘッドが大きい
- native-imageツールによるNative Image生成時間はかなりばらつきがあるため、CIツールなどで作成する場合はパイプライン中のタスクの最後に配置することを推奨。