Spring GraalVM Native 0.6.0 已發布

工程 | Andy Clement | 2020 年 4 月 9 日 | ...

Spring 團隊剛發布了 spring-graalvm-native 專案的 0.6.0 版本。 這個專案旨在讓嘗試建置 Spring 應用程式的 GraalVM 原生映像檔的人更容易。

如需深入了解 Spring 的原生映像檔,請參閱 Sébastien Deleuze 的 Devoxx 演講

在這篇部落格文章中,我們將討論自那時以來發生的變化,並引導您找到一些關鍵資源,讓您可以試用它! 這個專案位於 spring-projects-experimental github org 中,表示它仍在開發中,但我們有一些範例應用程式展示了已經運作的技術類型,以及大量關於如何使用您自己的應用程式進行實驗的文件。

什麼是 GraalVM 原生映像檔?

簡單來說,GraalVM 是一個可以被用於多種用途的總括性專案,但我們在這裡要關注的關鍵方面是將 JVM 程式碼作為原生映像檔執行。 一旦編譯成特定平台原生映像檔,應用程式應該具有非常快的啟動速度和更可靠的記憶體配置 (沒有 JIT 在開始時導致記憶體激增)。

建立映像檔時,原生映像檔建置工具需要知道您的應用程式的資訊,例如正在載入哪些資源、可能會被反射哪些類型,以及類型是否可以在建立映像檔時安全地初始化,或者必須在稍後的執行階段初始化。 這些資訊使原生映像檔工具能夠嘗試為應用程式建置最佳映像檔。

實際上,有幾種方法可以收集和傳達此配置

  • 某些函式庫直接將其包含在其發布版本中,作為固定的 .json 檔案 (例如 netty)
  • 第三方功能 (在 GraalVM 術語中) 參與建置過程,並計算資訊,並透過 API 將其傳遞給原生映像檔。 spring-graalvm-native 專案的一個關鍵方面是它包含的功能。 此功能了解 Spring Boot 應用程式的運作方式,將該知識應用於正在建置的特定應用程式,並將結果傳遞給原生映像檔建置過程。 它可以做出非常動態的決策,因為它可以根據封閉世界的假設運作,知道當映像檔建置發生時,類別路徑是完整/固定的。
  • 與 GraalVM 一起提供的代理程式可以收集應用程式正常執行 (作為 JVM 應用程式) 時將需要的配置資料,然後這些檔案會被後續的原生映像檔建置步驟採用。

每種計算配置的方法都有優缺點。 例如,代理程式只能收集在應用程式執行時執行的程式碼路徑上的資訊,但它肯定會建立精確所需內容的最佳集合 (在資源/反射存取方面)。 另一方面,該功能不會建立完全最佳的配置,因為它不會執行應用程式,因此必須允許可能或可能不採取的某些程式碼路徑,但是作為建置過程的一部分,該功能能夠執行特定於 Spring 的最佳化,例如搶先評估條件配置。 當原生映像檔建置執行時,已知完整的類別路徑,因此可以在該時間執行 @ConditionalOnClass 檢查,如果檢查失敗,則可以捨棄該配置,甚至在啟動產生的映像檔時也不會查看。

我們一直在努力地在所有這些方面改進生態系統,以便我們可以轉向一切正常運作的世界。 仍然有一段路要走! 我們正在深入研究 Tomcat,以使配置的提取像 netty 一樣容易。 與 GraalVM 團隊合作,我們一直在確保 Spring Boot 應用程式中沒有任何東西會導致原生映像檔建構失敗 (需要在雙方進行修復),並改進 spring-graalvm-native 功能以更好地理解更廣泛的 Spring 應用程式。 我們也一直在協助確保代理程式收集器不會遺漏任何東西。 我們目前與 GraalVM 團隊合作解決的一系列問題實際上追蹤 這裡

自 Spring One Platform 2019 和 Devoxx 的演示以來,該功能已經了解了更多關於 Boot 的資訊,代理程式遺漏的更少,GraalVM 更加相容,產生的映像檔大小已經減少,映像檔建置時間已經縮短,而且我們包含更多的範例專案來展示哪些正在運作。

我如何嘗試?

這裡有許多範例專案 這裡,甚至包括一個 PetClinic (當然!),以及相關的範例文件 這裡,說明如何使用它們。 有使用 Netty、Tomcat、Spring MVC、Spring WebFlux、JPA、Spring Cloud Function、kotlin 等的範例。 你可能會看到什麼?

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::
...
INFO: Started TomcatApplication in 0.044 seconds (JVM running for 0.62)

對於將其應用於您自己的專案,該文件描述了使用 功能代理程式或包含兩者的 混合模式 執行它的所有步驟。 混合模式有時是兩全其美的方法,因為代理程式可以捕獲該功能可能遺漏的東西,反之亦然。

如果它不起作用,我該怎麼辦?

這個過程還不是很順利,還有很多領域需要完成。 開發該功能的團隊和 GraalVM 團隊一直在努力改進診斷,以便在出現問題時,您仍然可以取得進展並了解下一步該怎麼做。 某些隨機應用程式不太可能第一次就起作用,但是對於任何致力於解決問題的人來說,許多應用程式都可以運作。 您的應用程式可能正在使用我們測試中尚未遇到的函式庫。 它可能正在使用該功能尚未學會的某些 Spring 行為。 它可能在映像檔建置時或在啟動已編譯的映像檔時出現問題。 這裡有一個疑難排解頁面 這裡,討論了一些常見問題以及如何解決這些問題。 遇到其他問題? 請在專案中 提出問題

spring-graalvm-native 專案中是一個配置子專案,它試圖以易於擴展的形式封裝有關 Spring Boot 行為的知識。 例如,它編碼了特定的匯入選擇器可能會導致需要對特定類型進行反射存取。 該功能本身是由這種封裝的知識驅動的,如果您發現該知識目前不足,請隨時增強它並貢獻回專案以建立該知識,請參閱 可擴展性指南

spring-graalvm-native 專案中還包含一些替換,替換是 GraalVM 術語,用於在映像檔建置時對現有類別進行更改,該類別目前在包含在原生映像檔中時效果不佳。 隨著時間的推移,該計劃仍然是消除這些替換,並與包含這些有問題的類別的專案合作,以將它們放入在原生映像檔內外都能運作的理想形式。

雖然 spring-graalvm-native 專注於 Spring,但顯然 Spring 專案通常包含許多第三方相依性。 其中許多尚未包含必要的配置,因此我們的功能正在盡可能地「涵蓋它們」。 在可能的情況下,我們的計劃仍然是與這些相依性提供者合作,以協助他們製作理想的原生映像檔配置,然後它將被原生映像檔建置自動提取。 GraalVM 代理程式 提供了一個不錯的方法來嘗試處理遺失配置的程式碼。

未來的發展方向

所有工作都僅在這個實驗性功能中進行嗎?遠遠不止於此。許多增強功能已納入 Spring,以確保它在建置到原生映像檔時能正常運作。例如,在 Spring Framework 中,Spring Framework 5.2 中的 @Configuration proxyBeanMethods 屬性,讓應用程式無需 CGLIB 代理即可執行(原生映像檔處理程序僅支援 JDK 代理)。我們也重構了 Spring Boot 條件處理中的一些類別載入,以使用不同的方法,因為代理程式無法捕獲原始的載入形式。

更多此類增強功能將陸續推出。這個功能還有更多東西需要學習,而核心 Spring 中仍然有太多在啟動時完成的工作,我們可以將其推送到建置時,這將對已建置原生映像檔的記憶體需求產生重大影響。這些改進不僅有益於建置到原生映像檔的應用程式,也有益於在常規 JVM 上執行的應用程式。情況只會越來越好!感謝 GraalVM 團隊在此工作中對我們的支持。若要追蹤我們的進度,請密切關注此專案

取得 Spring 電子報

隨時掌握 Spring 電子報的最新消息

訂閱

搶先一步

VMware 提供訓練和認證,以加速您的進度。

瞭解更多

取得支援

Tanzu Spring 在一個簡單的訂閱中提供對 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位檔。

瞭解更多

即將到來的活動

查看 Spring 社群中所有即將到來的活動。

查看全部