高效容器映象

將 Spring Boot 的 uber jar 打包成 Docker 映象非常容易。然而,將 uber jar 原樣複製並在 Docker 映象中執行存在各種缺點。不解壓執行 uber jar 時總是存在一定的開銷,在容器化環境中這會很明顯。另一個問題是,將你的應用程式碼及其所有依賴項放在 Docker 映象的同一層中並不理想。由於你重新編譯程式碼的頻率可能高於升級 Spring Boot 版本的頻率,因此將事物稍微分開通常更好。如果你將 jar 檔案放在應用類之前的層中,Docker 通常只需要更改最底層,就可以從其快取中獲取其他層。

Docker 映象分層

為了更容易建立最佳化的 Docker 映象,Spring Boot 支援向 jar 包新增分層索引檔案。它提供了一個層列表以及 jar 包中應包含在這些層中的部分。索引中的層列表按照應將層新增到 Docker/OCI 映象的順序進行排序。開箱即用地支援以下層:

  • dependencies(用於常規釋出的依賴項)

  • spring-boot-loader(用於 org/springframework/boot/loader 下的所有內容)

  • snapshot-dependencies(用於快照依賴項)

  • application(用於應用類和資源)

下面顯示了一個 layers.idx 檔案的示例:

- "dependencies":
  - BOOT-INF/lib/library1.jar
  - BOOT-INF/lib/library2.jar
- "spring-boot-loader":
  - org/springframework/boot/loader/launch/JarLauncher.class
  - ... <other classes>
- "snapshot-dependencies":
  - BOOT-INF/lib/library3-SNAPSHOT.jar
- "application":
  - META-INF/MANIFEST.MF
  - BOOT-INF/classes/a/b/C.class

此分層設計旨在根據程式碼在應用構建之間更改的可能性進行分離。庫程式碼在構建之間更改的可能性較小,因此將其放置在其自己的層中,以便工具可以從快取中重用這些層。應用程式碼在構建之間更改的可能性較大,因此將其隔離在單獨的層中。

Spring Boot 也支援藉助 layers.idx 對 war 檔案進行分層。

對於 Maven,請參閱打包分層 jar 或 war 部分,瞭解如何向歸檔中新增分層索引的更多詳細資訊。對於 Gradle,請參閱 Gradle 外掛文件的打包分層 jar 或 war 部分