Slide 1

Slide 1 text

SpringBoot 3.0 の Native Image を試してみた

Slide 2

Slide 2 text

自己紹介 妹尾 一弘 サーバーサイドエンジニア 最近Web 開発から遠のいている LT 駆動学習 Java Do スタッフ

Slide 3

Slide 3 text

Spring Boot 3.0 リリース 🎉

Slide 4

Slide 4 text

Native Image のサポートがGA

Slide 5

Slide 5 text

Native Image 単独で実行可能となるようにビルドされたイメージ 起動時間が高速 メモリ使用量が削減できる コンテナイメージを縮小できる 完全に互換ではない

Slide 6

Slide 6 text

やってみた

Slide 7

Slide 7 text

サンプルコード 簡単なCRUD を行うREST API DynamoDB にアクセス

Slide 8

Slide 8 text

Bean @Data public class Item { private String id; private String name; private String code; }

Slide 9

Slide 9 text

Controller @RestController @RequestMapping("/items") public class ItemController { @Autowired private ItemService service; @GetMapping("/") public Iterable index() { return service.list(); }

Slide 10

Slide 10 text

Service @Service public class ItemService { @Autowired private ItemRepository repository; public void create(Item item) { repository.save(item); }

Slide 11

Slide 11 text

Repository public interface ItemRepository { Item save(Item item); Iterable findAll(); Optional findById(String id); void deleteById(String id); }

Slide 12

Slide 12 text

ビルド

Slide 13

Slide 13 text

Gradle plugins plugins { id 'java' id 'org.springframework.boot' version '3.0.1' id 'io.spring.dependency-management' version '1.1.0' id 'org.graalvm.buildtools.native' version '0.9.18' }

Slide 14

Slide 14 text

bootBuildImage タスク Spring Boot Plugin のタスク Cloud Native Buildpacks を利用してビルド ソースコードからビルド構成を検知 Native BuildTools プラグインがある時Native Build

Slide 15

Slide 15 text

bootBuildImage ./gradlew bootBuildImage --imageName spring-boot-3:latest docker push ...

Slide 16

Slide 16 text

潤沢なメモリが必要 自分のローカルマシンだとOOME 今回はAWS CodeBuild を利用してビルド 15 GB メモリ、8 vCPU のインスタンス

Slide 17

Slide 17 text

問題なく動いたか?

Slide 18

Slide 18 text

問題 - CASE 1 - DB アクセスにサードパーティライブラリを利用 spring-data-dynamodb dependencies { implementation 'com.github.derjust:spring-data-dynamodb:5.1.0' }

Slide 19

Slide 19 text

Bean 生成エラー( 実行時エラー)

Slide 20

Slide 20 text

原因 - CASE 1 - AWS SDK for Java は v2 以降からNativeImage に対応 該当ライブラリはv1 にしか対応していなかった

Slide 21

Slide 21 text

対策 - CASE 1 - 公式のdynamodb-enhanced を利用 dependencies { implementation 'software.amazon.awssdk:dynamodb' implementation 'software.amazon.awssdk:dynamodb-enhanced' }

Slide 22

Slide 22 text

対策 - CASE 1 - Bean とDynamoDB Table のマッピングを生成 @Bean DynamoDbTable itemTable(DynamoDbEnhancedClient client) { return client.table("Items", TableSchema.fromBean(Item.class)); }

Slide 23

Slide 23 text

対策 - CASE 1 - Repository を独自実装 @Component public class ItemRepositoryImpl implements ItemRepository { @Autowired private DynamoDbTable table; @Override public Item save(Item item) { table.putItem(item); return item; }

Slide 24

Slide 24 text

問題 - CASE 2 - Bean 生成エラー( 実行時エラー)

Slide 25

Slide 25 text

原因 - CASE 2 - dynamodb-enhanced も一部非対応

Slide 26

Slide 26 text

対策 - CASE 2 - StaticTableSchema を利用 private TableSchema getStaticTableSchema() { return StaticTableSchema.builder(Item.class) .newItemSupplier(Item::new) .addAttribute(String.class, a -> a.name("id").setter(Item::se .addAttribute(String.class, a -> a.name("name").setter(Item:: .addAttribute(String.class, a -> a.name("code").setter(Item:: .build(); }

Slide 27

Slide 27 text

成功!

Slide 28

Slide 28 text

性能比較

Slide 29

Slide 29 text

イメージサイズ plane: 17-jdk-alpine 上にbootJar を配備 220MB ⇒ 43MB に改善

Slide 30

Slide 30 text

メモリ使用量

Slide 31

Slide 31 text

起動速度 - bootJar - 起動時間: 14.354s

Slide 32

Slide 32 text

起動速度 - native - 起動時間: 0.596s

Slide 33

Slide 33 text

まとめ SpringBoot の起動時間は高速になる メモリ使用量は今回は参考程度 あまり負荷もかけていない イメージサイズの節約も嬉しい

Slide 34

Slide 34 text

課題 ライブラリがNative 対応してるか調査コストが高い 実行時エラーになるので確認に時間がかかる いい調査方法をご存知の方は教えて下さい

Slide 35

Slide 35 text

ありがとうございました