MicronautでGraalVM native imageを動かす
Introduction
前回はMicronautフレームワークについて紹介しました。
MicronautはGraalVMで動作するアプリも簡単にできるので、
今回はそれを試してみます。
Using GraalVM with Micronaut
About GraalVM
GraalVMとは、最近注目されている多言語対応の仮想マシンとプラットフォームです。
現在はJavaやJVM言語(ScalaとかClojureとか)の実行機能に加え、
node.js(JavaScript)/Ruby/Python/R言語/LLVMベースの言語をサポートしています。
これにより、複数のプログラミング言語が混在したプログラムを実行することも可能になります。
また、GraalVMではJavaプログラムをネイティブコンパイルすることができます。
こうすることで高速起動&フットプリントが小さいネイティブプログラムを作成することが可能です。
Words related to GraalVM
- Graal : JavaのJITコンパイラ
- GraalVM : Graalを中心とした多言語対応仮想マシンとプラットフォーム
- SubstrateVM : 埋め込み用途に適した軽量VM
- Truffle : インタプリタ構築用ツールおよびAPI
SubstrateVMについてはここ、
Truffleについてはここを参照。
GraalはJavaのJITコンパイラ、
GraalVMはJITコンパイラにGraalを使っている仮想マシンとプラットフォームを指します。
Advantages of GraalVM
GraalVMを使ってうれしいことの1つは、複数言語を1つのランタイムで動かせることです。
これによってシステムの構成を言語ごとに変更する必要がなくなります。
そしてもう1つ、アプリの起動がとても高速になるというメリットがあります。
GraalVMではAOTコンパイラをつかってnative imageを作成することができるので。
これにより起動が高速化します。
※AOTコンパイラで事前にVM上で動作する言語にコンパイルされるため起動が速くなる
例えばAWS Lambdaなどのserverless環境でGraalVMを使用する場合、
実行コンテキスト起動時ロードの高速化が可能になります。
Develop sample application
ではMicronautでGraalVMのnative imageを動かしてみましょう。
まずはSDKMANを使ってGraalVMをインストールします。
また、前回を参考にMicronautもインストールしましょう。
※先日、Micronaut 1.2がリリースされました
% sdk install java 19.1.1-grl % sdk use java 19.1.1-grl Using java version 19.1.1-grl in this shell.
javaコマンドで使っているJVMを確認。
% java -version openjdk version "1.8.0_222" OpenJDK Runtime Environment (build 1.8.0_222-20190711112007.graal.jdk8u-src-tar-gz-b08) OpenJDK 64-Bit GraalVM CE 19.1.1 (build 25.222-b08-jvmci-19.1-b01, mixed mode)
準備ができたらmnコマンドで、graal-native-image featureを指定してアプリの雛形を作成します。
% mn create-app hello-graal --features graal-native-image
適当なコントローラクラスを作成。
package hello.graal; import io.micronaut.http.MediaType; import io.micronaut.http.annotation.*; //src/main/java/hello/graal/HelloController.java @Controller("/hello") public class HelloController { @Get(produces = MediaType.TEXT_PLAIN) public String index() { return "Hello Micronaut from GraalVM!"; } }
まずは普通にrunしてみます。
% cd path/your/graal-app % ./gradlew run > Task :run 22:12:59.185 [main] INFO io.micronaut.runtime.Micronaut - Startup completed in 7713ms. Server Running: http://localhost:8080
起動に7713ミリ秒かかりました。
では次にnative imageを作成して実行してみましょう。
native-imageコマンドを利用するため、gu installでnative-imageをインストールします。
% cd path/rour/graal-app gu install native-image
gradle assembleでnative imageを作ります。
image作成はけっこう時間かかります。
$ ./gradlew assemble hello-graal native-image --no-server -cp build/libs/hello-graal-0.1-all.jar [hello-graal:54971] classlist: 10,659.98 ms [hello-graal:54971] (cap): 4,312.39 ms [hello-graal:54971] setup: 12,598.84 ms [hello-graal:54971] (typeflow): 111,565.10 ms [hello-graal:54971] (objects): 43,374.50 ms [hello-graal:54971] (features): 8,006.12 ms [hello-graal:54971] analysis: 184,597.60 ms [hello-graal:54971] (clinit): 2,869.04 ms [hello-graal:54971] universe: 13,006.53 ms [hello-graal:54971] (parse): 14,518.54 ms [hello-graal:54971] (inline): 36,025.61 ms [hello-graal:54971] (compile): 96,351.35 ms [hello-graal:54971] compile: 170,146.60 ms [hello-graal:54971] image: 10,961.05 ms [hello-graal:54971] write: 3,159.46 ms [hello-graal:54971] [total]: 441,090.72 ms
生成したnative imageを実行してみます。
% ./hello-graal 22:12:01.299 [main] INFO io.micronaut.runtime.Micronaut - Startup completed in 137ms. Server Running: http://localhost:8080
普通に起動したとき7713ミリ秒かかっていた時間が、
native imageだと137ミリ秒と非常に高速で起動しています。
Conclusion
今回はMicronautでGraalVMのnative imageを作成して実行してみました。
とても起動が速くなり、AWS Lambdaではうってつけといわれるのも理解できます。
次はAWS Lambda上でMicronaut + GraalVMをやってみたいと思います。