SlideShare a Scribd company logo
Spring Native について
既存の Spring Boot アプリ で Spring Native を
サポートしたときの話
三辻尚栄 (株)ナチュラルスタイル
2021年9月
Spring Native とは
Spring Native とは
1. Graal VM の Native Image 機能を使って
2. Spring Boot アプリをビルドすることを
3. サポートするプロジェクト
https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/
Spring Native とは
1. Graal VM の Native Image 機能を使って
2. Spring Boot アプリをビルドすることを
3. サポートするプロジェクト
Java で 書かれた Spring Boot アプリを
C/C++ や Go, Rust で書かれたアプリのように
ネイティブの実行形式にビルドできるようになる
https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/
Spring Native がうれしい場面
Spring Native がうれしい場面
● (Webアプリの)起動が速くなる(事前コンパイル)
● 必要なメモリが少なくなる
メリット
Spring Native がうれしい場面
● (Webアプリの)起動が速くなる(事前コンパイル)
● 必要なメモリが少なくなる
メリット
● VMによる実行時の最適化が無効になる
(実行時の再コンパイル不可)
● 機能的な制約がある(対応策あり)
● ビルドに時間がかかる (数十分単位)
デメリット
Spring Native がうれしい場面
● (Webアプリの)起動が速くなる(事前コンパイル)
● 必要なメモリが少なくなる
● コンテナ化されたマイクロサービス(起動時間、メモリ)
● FaaS (サーバーレスアプリ) (起動時間)
● コマンドラインツール(起動時間)
メリット
● VMによる実行時の最適化が無効になる
(実行時の再コンパイル不可)
● 機能的な制約がある(対応策あり)
● ビルドに時間がかかる (数十分単位)
デメリット
うれしい場面
https://speakerdeck.com/hhiroshell/graalvm-for-beginners?slide=30
Spring Native がうれしい場面
うれしくない場面もあります!
何にでも使えるわけではありません
There is no one silver bullet.
Graal VM とは
Graal VM とは
1. JVM言語(Java,kotlin,...)で書かれたプログラムと
2. それ以外の言語(JavaScript,Ruby,Python,...)で書かれたプログラムに
3. 高パフォーマンスをもたらすための JDK の亜種
https://www.graalvm.org/docs/introduction/
Graal VM とは
1. JVM言語(Java,kotlin,...)で書かれたプログラムと
2. それ以外の言語(JavaScript,Ruby,Python,...)で書かれたプログラムに
3. 高パフォーマンスをもたらすための JDK の亜種
https://www.graalvm.org/docs/introduction/
One VM to Rule Them All
Graal VM とは
1. JVM言語(Java,kotlin,...)で書かれたプログラムと
2. それ以外の言語(JavaScript,Ruby,Python,...)で書かれたプログラムに
3. 高パフォーマンスをもたらすための JDK の亜種
https://www.graalvm.org/docs/introduction/
One VM to Rule Them All
この世のすべてを統(す)べる 唯一のVM
http://lafo.ssw.uni-linz.ac.at/papers/2013_Onward_OneVMToRuleThemAll.pdf
Graal VM を構成するもの
Graal VM を構成するもの
Graal Compiler
Java で書かれた Byte Code - Machine Code コンパイラ
● JIT時にJVMから呼ばれ���
● Java で改造・拡張可能 (Java で Java その1)
Graal VM を構成するもの
Native Image
Graal Compiler を AOT (事前コンパイル) に使うための仕組み
● ビルドされたバイナリは JVM (java.exe) なしで実行可能
● スレッド管理, GCなどは Substrate VM を埋め込んで処理
Graal Compiler
Java で書かれた Byte Code - Machine Code コンパイラ
● JIT時にJVMから呼ばれる
● Java で改造・拡張可能 (Java で Java その1)
Graal VM を構成するもの
Truffle
Java で他の言語のインタプリタを楽に実装するための API
● 最適化に役立つヒントを含んだ言語構文を Javaで定義するだけでOK
● インタプリタそのもの -> 既存の仕組みを流用
● 最適化処理そのもの -> 既存の仕組みを流用
● JavaScript, Ruby, Python, LLVM, wasm,… が対応済
● Java 自体も対応済 (Java で Java その2)
Native Image
Graal Compiler を AOT (事前コンパイル) に使うための仕組み
● ビルドされたバイナリは JVM (java.exe) なしで実行可能
● スレッド管理, GCなどは Substrate VM を埋め込んで処理
Graal Compiler
Java で書かれた Byte Code - Machine Code コンパイラ
● JIT時にJVMから呼ばれる
● Java で改造・拡張可能 (Java で Java その1)
Spring Native とは (再)
1. Graal VM の Native Image 機能を使って
2. Spring Boot アプリをビルドすることを
3. サポートするプロジェクト
Java で 書かれた Spring Boot アプリを
C/C++ や Go, Rust で書かれたアプリのように
ネイティブの実行形式にビルドできるようになる
https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/
既存アプリで Spring Native をサポートする
既存アプリで Spring Native をサポートする
Spring Boot を 2.5.x にバージョンアップ
1. pom.xml の編集
2. 各種ライブラリのアップデート
3. logback-spring.xml の コード化
4. 動作確認する
既存アプリで Spring Native をサポートする
Spring Boot を 2.5.x にバージョンアップ
1. pom.xml の編集
2. 各種ライブラリのアップデート
3. logback-spring.xml の コード化
4. 動作確認する
Native Image サポート
1. pom.xml の編集
2. META-INF ディレクトリ作成
3. ビルドと実行を繰り返しながら調整
4. 動作確認
5. Build Pack (Dockerイメージ生成)
Spring Boot を 2.5.x にバージョンアップ
Spring Boot を 2.5.x にバージョンアップ
1. pom.xml を編集
● update spring-boot-starter-parent: 2.2.6.RELEASE -> 2.5.4
● update maven-compiler-plugin: 1.8 -> 11 (ついで)
Spring Boot を 2.5.x にバージョンアップ
1. pom.xml を編集
● update spring-boot-starter-parent: 2.2.6.RELEASE -> 2.5.4
● update maven-compiler-plugin: 1.8 -> 11 (ついで)
2. 各種ライブラリのアップデート
● junit の dependency を追加
● update micrometer: 1.4.1 -> 1.7.3
● update prometheus: 0.8.1 -> 0.11.0
● update springfox-swagger2: 2.9.2 -> 3.0.0
○ @EnableSwagger2 無効化, springfox-boot-starter サポート
● lettuce ライブラリで RedisURI を初期化している箇所のコード修正
手元のプロジェクトで必要だったもの
Spring Boot を 2.5.x にバージョンアップ
1. pom.xml を編集
2. 各種ライブラリのアップデート
3. logback-spring.xml の コード化
Spring Native は logback の DI 機能をまだサポートしていないため、
XMLで設定していた部分を Javaのコードで書き直す必要があります。
Spring Native からは独立した部分なので、事前に対応しておきます。
https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/#logback-workaround
Spring Boot プロジェクト内で参考になりそうなコードを発見 !
このJavaコードが
src/main/java/org/springframework/boot/logging/logback/DefaultLogbackConfiguration.java
これらのXML設定をコード化したものと思われる
src/main/resources/org/springframework/boot/logging/logback/base.xml
src/main/resources/org/springframework/boot/logging/logback/defaults.xml
src/main/resources/org/springframework/boot/logging/logback/console-appender.xml
src/main/resources/org/springframework/boot/logging/logback/file-appender.xml
Spring Boot を 2.5.x にバージョンアップ
1. pom.xml を編集
2. 各種ライブラリのアップデート
3. logback-spring.xml の コード化
Spring Native は logback の DI 機能をまだサポートしていないため、
XMLで設定していた部分を Javaのコードで書き直す必要があります。
Spring Native からは独立した部分なので、事前に対応しておきます。
https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/#logback-workaround
4. 動作確認する
Native 化前に正しく動作しないものは�� Native 化後も正しく動作しません。
Native 化前にしっかり動作確認をしておきましょう。
自動テストがある場合は自動テストを行うことをおすすめします。
また、Native 化前の状態で本番に投入可能であればしばらく動作させて安定
していることを確認することをおすすめします。
Native Image サポート
Native Image サポート
1. pom.xml を編集
● 2.2. Getting started with Native Build Tools を参考に編集する
● spring-boot-devtools の dependency を無効化する
※ 引き続き JIT版のビルドもできますが spring-aot-maven-plugin の有効/無効で
生成される jar が微妙に異なるようなので注意 !
Native Image サポート
1. pom.xml を編集
● 2.2. Getting started with Native Build Tools を参考に編集する
● spring-boot-devtools の dependency を無効化する
● springfox-boot-starter の dependency を無効化する
2. META-INF ディレクトリ作成
● プロジェクト内にディレクトリ
src/main/resources/META-INF/native-image/<groupId>/<artifactId> を作成する
● ファイル native-image.properties を作成する
● ファイル proxy-config.json を作成する (一旦0バイトでOK)
● ファイル reflect-config.json を作成する (一旦0バイトでOK)
● ファイル serialization-config.json を作成する (一旦0バイトでOK)
Args = -H:NumberOfThreads=4 
--enable-url-protocols=https 
--initialize-at-build-time=org.springframework.boot.logging.logback.ColorConverter
(参考)
Native Image サポート
1. pom.xml を編集
2. META-INF ディレクトリ作成
3. ビルドと実行を繰り返しながら調整
● 上のコマンドでビルドを試す
-> エラーが発生したら2.で作った設定ファイルに記述を追加する
● ビルドが通ったらネイティブバイナリを実行してみる
-> エラーが発生したら2.で作った設定ファイルに記述を追加する
$ mvn -Pnative -DskipTests package
エラーの原因は、メモリ不足もしくは、型の動的生成、Reflection, Dynamic Proxy などの
Native でサポートされない機能を使おうとしていることがほとんどです。
ほとんどの場合、エラーメッセージにしたがって設定ファイルに記述することで改善できます。
設定ファイルについては Graal VM のドキュメントを参照のこと。
https://www.graalvm.org/reference-manual/native-image/BuildConfiguration/
https://www.graalvm.org/reference-manual/native-image/Reflection/
https://www.graalvm.org/reference-manual/native-image/DynamicProxy/
Tracing Agent という設定自動化ツールもありますが、私は上手く使えませんでした。
https://www.graalvm.org/reference-manual/native-image/Agent/
Native Image サポート
1. pom.xml を編集
2. META-INF ディレクトリ作成
3. ビルドと実行を繰り返しながら調整
4. 動作確認
ビルドは通っても実行時にエラーが発生する可能性があるため、動作確認します。
自動テストがある場合は自動テストを行うことをおすすめします。
Native Image サポート
1. pom.xml を編集
2. META-INF ディレクトリ作成
3. ビルドと実行を繰り返しながら調整
4. 動作確認
ビルドは通っても実行時にエラーが発生する可能性があるため、動作確認します。
自動テストがある場合は自動テストを行うことをおすすめします。
5. Build Pack (Dockerイメージ生成)
2.1. Getting started with Buildpacks を参考に pom.xml に記述を追加して
Docker イメージの生成を試します。
4. までがうまくいっていれば、うまくいくことでしょう。
既存アプリで Spring Native をサポートする(再)
Spring Boot を 2.5.x にバージョンアップ
1. pom.xml の編集
2. 各種ライブラリのアップデート
3. logback-spring.xml の コード化
4. 動作確認する
Native Image サポート
1. pom.xml の編集
2. META-INF ディレクトリ作成
3. ビルドと実行を繰り返しながら調整
4. 動作確認
5. Build Pack (Dockerイメージ生成)
おしまい

More Related Content

Spring native について

  • 1. Spring Native について 既存の Spring Boot アプリ で Spring Native を サポートしたときの話 三辻尚栄 (株)ナチュラルスタイル 2021年9月
  • 3. Spring Native とは 1. Graal VM の Native Image 機能を使って 2. Spring Boot アプリをビルドすることを 3. サポートするプロジェクト https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/
  • 4. Spring Native とは 1. Graal VM の Native Image 機能を使って 2. Spring Boot アプリをビルドすることを 3. サポートするプロジェクト Java で 書かれた Spring Boot アプリを C/C++ や Go, Rust で書かれたアプリのように ネイティブの実行形式にビルドできるようになる https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/
  • 6. Spring Native がうれしい場面 ● (Webアプリの)起動が速くなる(事前コンパイル) ● 必要なメモリが少なくなる メリット
  • 7. Spring Native がうれしい場面 ● (Webアプリの)起動が速くなる(事前コンパイル) ● 必要なメモリが少なくなる メリット ● VMによる実行時の最適化が無効になる (実行時の再コンパイル不可) ● 機能的な制約がある(対応策あり) ● ビルドに時間がかかる (数十分単位) デメリット
  • 8. Spring Native がうれしい場面 ● (Webアプリの)起動が速くなる(事前コンパイル) ● 必要なメモリが少なくなる ● コンテナ化されたマイクロサービス(起動時間、メモリ) ● FaaS (サーバーレスアプリ) (起動時間) ● コマンドラインツール(起動時間) メリット ● VMによる実行時の最適化が無効になる (実行時の再コンパイル不可) ● 機能的な制約がある(対応策あり) ● ビルドに時間がかかる (数十分単位) デメリット うれしい場面 https://speakerdeck.com/hhiroshell/graalvm-for-beginners?slide=30
  • 11. Graal VM とは 1. JVM言語(Java,kotlin,...)で書かれたプログラムと 2. それ以外の言語(JavaScript,Ruby,Python,...)で書かれたプログラムに 3. 高パフォーマンスをもたらすための JDK の亜種 https://www.graalvm.org/docs/introduction/
  • 12. Graal VM とは 1. JVM言語(Java,kotlin,...)で書かれたプログラムと 2. それ以外の言語(JavaScript,Ruby,Python,...)で書か��たプログラムに 3. 高パフォーマンスをもたらすための JDK の亜種 https://www.graalvm.org/docs/introduction/ One VM to Rule Them All
  • 13. Graal VM とは 1. JVM言語(Java,kotlin,...)で書かれたプログラムと 2. それ以外の言語(JavaScript,Ruby,Python,...)で書かれたプログラムに 3. 高パフォーマンスをもたらすための JDK の亜種 https://www.graalvm.org/docs/introduction/ One VM to Rule Them All この世のすべてを統(す)べる 唯一のVM http://lafo.ssw.uni-linz.ac.at/papers/2013_Onward_OneVMToRuleThemAll.pdf
  • 15. Graal VM を構成するもの Graal Compiler Java で書かれた Byte Code - Machine Code コンパイラ ● JIT時にJVMから呼ばれる ● Java で改造・拡張可能 (Java で Java その1)
  • 16. Graal VM を構成するもの Native Image Graal Compiler を AOT (事前コンパイル) に使うための仕組み ● ビルドされたバイナリは JVM (java.exe) なしで実行可能 ● スレッド管理, GCなどは Substrate VM を埋め込んで処理 Graal Compiler Java で書かれた Byte Code - Machine Code コンパイラ ● JIT時にJVMから呼ばれる ● Java で改造・拡張可能 (Java で Java その1)
  • 17. Graal VM を構成するもの Truffle Java で他の言語のインタプリタを楽に実装するための API ● 最適化に役立つヒントを含んだ言語構文を Javaで定義するだけでOK ● インタプリタそのもの -> 既存の仕組みを流用 ● 最適化処理そのもの -> 既存の仕組みを流用 ● JavaScript, Ruby, Python, LLVM, wasm,… が対応済 ● Java 自体も対応済 (Java で Java その2) Native Image Graal Compiler を AOT (事前コンパイル) に使うための仕組み ● ビルドされたバイナリは JVM (java.exe) なしで実行可能 ● スレッド管理, GCなどは Substrate VM を埋め込んで処理 Graal Compiler Java で書かれた Byte Code - Machine Code コンパイラ ● JIT時にJVMから呼ばれる ● Java で改造・拡張可能 (Java で Java その1)
  • 18. Spring Native とは (再) 1. Graal VM の Native Image 機能を使って 2. Spring Boot アプリをビルドすることを 3. サポートするプロジェクト Java で 書かれた Spring Boot アプリを C/C++ や Go, Rust で書かれたアプリのように ネイティブの実行形式にビルドできるようになる https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/
  • 19. 既存アプリで Spring Native をサポートする
  • 20. 既存アプリで Spring Native をサポートする Spring Boot を 2.5.x にバージョンアップ 1. pom.xml の編集 2. 各種ライブラリのアップデート 3. logback-spring.xml の コード化 4. 動作確認する
  • 21. 既存アプリで Spring Native をサポートする Spring Boot を 2.5.x にバージョンアップ 1. pom.xml の編集 2. 各種ライブラリのアップデート 3. logback-spring.xml の コード化 4. 動作確認する Native Image サポート 1. pom.xml の編集 2. META-INF ディレクトリ作成 3. ビルドと実行を繰り返しながら調整 4. 動作確認 5. Build Pack (Dockerイメージ生成)
  • 22. Spring Boot を 2.5.x にバージョンアップ
  • 23. Spring Boot を 2.5.x にバージョンアップ 1. pom.xml を編集 ● update spring-boot-starter-parent: 2.2.6.RELEASE -> 2.5.4 ● update maven-compiler-plugin: 1.8 -> 11 (ついで)
  • 24. Spring Boot を 2.5.x にバージョンアップ 1. pom.xml を編集 ● update spring-boot-starter-parent: 2.2.6.RELEASE -> 2.5.4 ● update maven-compiler-plugin: 1.8 -> 11 (ついで) 2. 各種ライブラリのアップデート ● junit の dependency を追加 ● update micrometer: 1.4.1 -> 1.7.3 ● update prometheus: 0.8.1 -> 0.11.0 ● update springfox-swagger2: 2.9.2 -> 3.0.0 ○ @EnableSwagger2 無効化, springfox-boot-starter サポート ● lettuce ライブラリで RedisURI を初期化している箇所のコード修正 手元のプロジェクトで必要だったもの
  • 25. Spring Boot を 2.5.x にバージョンアップ 1. pom.xml を編集 2. 各種ライブラリのアップデート 3. logback-spring.xml の コード化 Spring Native は logback の DI 機能をまだサポートしていないため、 XMLで設定していた部分を Javaのコードで書き直す必要があります。 Spring Native からは独立した部分なので、事前に対応しておきます。 https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/#logback-workaround Spring Boot プロジェクト内で参考になりそうなコードを発見 ! このJavaコードが src/main/java/org/springframework/boot/logging/logback/DefaultLogbackConfiguration.java これらのXML設定をコード化したものと思われる src/main/resources/org/springframework/boot/logging/logback/base.xml src/main/resources/org/springframework/boot/logging/logback/defaults.xml src/main/resources/org/springframework/boot/logging/logback/console-appender.xml src/main/resources/org/springframework/boot/logging/logback/file-appender.xml
  • 26. Spring Boot を 2.5.x にバージョンアップ 1. pom.xml を編集 2. 各種ライブラリのアップデート 3. logback-spring.xml の コード化 Spring Native は logback の DI 機能をまだサポートしていないため、 XMLで設定していた部分を Javaのコードで書き直す必要があります。 Spring Native からは独立した部分なので、事前に対応しておきます。 https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/#logback-workaround 4. 動作確認する Native 化前に正しく動作しないものは、 Native 化後も正しく動作しません。 Native 化前にしっかり動作確認をしておきましょう。 自動テストがある場合は自動テストを行うことをおすすめします。 また、Native 化前の状態で本番に投入可能であればしばらく動作させて安定 していることを確認することをおすすめします。
  • 28. Native Image サポート 1. pom.xml を編集 ● 2.2. Getting started with Native Build Tools を参考に編集する ● spring-boot-devtools の dependency を無効化する ※ 引き続き JIT版のビルドもできますが spring-aot-maven-plugin の有効/無効で 生成される jar が微妙に異なるようなので注意 !
  • 29. Native Image サポート 1. pom.xml を編集 ● 2.2. Getting started with Native Build Tools を参考に編集する ● spring-boot-devtools の dependency を無効化する ● springfox-boot-starter の dependency を無効化する 2. META-INF ディレクトリ作成 ● プロジェクト内にディレクトリ src/main/resources/META-INF/native-image/<groupId>/<artifactId> を作成する ● ファイル native-image.properties を作成する ● ファイル proxy-config.json を作成する (一旦0バイトでOK) ● ファイル reflect-config.json を作成する (一旦0バイトでOK) ● ファイル serialization-config.json を作成する (一旦0バイトでOK) Args = -H:NumberOfThreads=4 --enable-url-protocols=https --initialize-at-build-time=org.springframework.boot.logging.logback.ColorConverter (参考)
  • 30. Native Image サポート 1. pom.xml を編集 2. META-INF ディレクトリ作成 3. ビルドと実行を繰り返しながら調整 ● 上のコマンドでビルドを試す -> エラーが発生したら2.で作った設定ファイルに記述を追加する ● ビルドが通ったらネイティブバイナリを実行してみる -> エラーが発生したら2.で作った設定ファイルに記述を追加する $ mvn -Pnative -DskipTests package エラーの原因は、メモリ不足もしくは、型の動的生成、Reflection, Dynamic Proxy などの Native でサポートされない機能を使おうとしていることがほとんどです。 ほとんどの場合、エラーメッセージにしたがって設定ファイルに記述することで改善できます。 設定ファイルについては Graal VM のドキュメントを参照のこと。 https://www.graalvm.org/reference-manual/native-image/BuildConfiguration/ https://www.graalvm.org/reference-manual/native-image/Reflection/ https://www.graalvm.org/reference-manual/native-image/DynamicProxy/ Tracing Agent という設定自動化ツールもありますが、私は上手く使えませんでした。 https://www.graalvm.org/reference-manual/native-image/Agent/
  • 31. Native Image サポート 1. pom.xml を編集 2. META-INF ディレクトリ作成 3. ビルドと実行を繰り返しながら調整 4. 動作確認 ビルドは通っても実行時にエラーが発生する可能性があるため、動作確認します。 自動テストがある場合は自動テストを行うことをおすすめします。
  • 32. Native Image サポート 1. pom.xml を編集 2. META-INF ディレクトリ作成 3. ビルドと実行を繰り返しながら調整 4. 動作確認 ビルドは通っても実行時にエラーが発生する可能性があるため、動作確認します。 自動テストがある場合は自動テストを行うことをおすすめします。 5. Build Pack (Dockerイメージ生成) 2.1. Getting started with Buildpacks を参考に pom.xml に記述を追加して Docker イメージの生成を試します。 4. までがうまくいっていれば、うまくいくことでしょう。
  • 33. 既存アプリで Spring Native をサポートする(再) Spring Boot を 2.5.x にバージョンアップ 1. pom.xml の編集 2. 各種ライブラリのアップデート 3. logback-spring.xml の コード化 4. 動作確認する Native Image サポート 1. pom.xml の編集 2. META-INF ディレクトリ作成 3. ビルドと実行を繰り返しながら調整 4. 動作確認 5. Build Pack (Dockerイメージ生成)