Spring 官宣了,幹掉原生 JVM!

Spring 團隊日前發佈了 Spring Native Beta 版。通過 Spring Native,Spring 應用將有機會與 GraalVM 原生鏡像的方式運行。爲了更好地支持原生運行,Spring Native 提供了 Maven 和 Gradle 插件,並且提供了優化原生配置的註解。

Spring 發佈了 Spring Native 的 beta 版本,並在 http://start.spring.io 上運行它。

實際上,這意味着自 Spring 成立以來,除了 Spring 支持的常規 Java 虛擬機之外,我們還將添加 Beta 支持,以使用 GraalVM 將 Spring 應用程序編譯到本機映像中,從而提供一種部署 Spring 應用程序的新方法。支持 Java 和 Kotlin。

這些本機 Spring 應用程序可以部署爲獨立的可執行文件(無需安裝 JVM),並提供有趣的特性,包括幾乎即時啓動(通常 < 100ms),即時峯值性能和較低的內存消耗,但所需的構建時間和運行時優化次數少於 JVM。

使用簡單mvn spring-boot:build-imagegradle bootBuildImage命令,您可以生成一個優化的容器映像,該映像將包含一個最小的 OS 層和一個小的本機可執行文件,該映像僅隨附 JDK,Spring 以及您在應用程序中使用的依賴項中的必需位。請參閱下面的示例,其中包含 50MB 可執行文件的最小容器映像,其中包含 Spring Boot,Spring MVC,Jackson,Tomcat,JDK 和應用程序。

這種原生方式,在很多場景下都會對 Spring 應用產生價值:

在使用場景上,比如 Piotr Mińkowski 提供了一個非常棒的指南,介紹瞭如何在 Knative 上使用 Spring Boot 和 GraalVM 構建原生微服務。

1. 團隊協作

Spring Native beta 是整個 Spring 團隊及其家族項目廣泛合作的結果:Spring Framework、Spring Boot 還包括 Spring Data、Spring Security、Spring Cloud 和 Spring Initializr。

據悉,原生功能的工作範圍比 Spring 更廣,因爲原生涉及到更廣泛的 JVM 生態系統,所以官方一直在與 GraalVM 團隊合作,以改善原生鏡像的兼容性和資源消耗。

以下是來自 GraalVM 團隊的 Vojin Jovanovic 的一段話。

“與 Spring 團隊協作打造原生 JVM 生態系統是一件非常愉快的事情:他們深厚的技術知識,再加上對社區的敏感觸覺,總是能帶來最好的解決方案。最新的 Spring Native 版本,以及它在 JVM 生態系統中的衆多用法,爲原生編譯的廣泛採用鋪平了道路。”

  1. 支持範圍

隨着 Spring Native 從 alpha 過渡到 beta,我認爲弄清我們提供的支持範圍很重要。

Alpha 是第一步,我們進行了大量試驗並完善了 Spring Native(以前稱爲 Spring GraalVM Native)的體系結構,兼容性和對一系列樣本進行了重大更改的封裝。我們還報告了 GraalVM 團隊修復的許多問題,目的是縮小 JVM 與 Spring 應用程序的本機之間的差距。

雖然仍被認爲是實驗性的,但 beta 意味着 Spring 現在爲 Spring 生態系統的子集提供了對 native 的支持。如果項目正在使用受支持的依賴項,則可以在項目上進行嘗試;如果出現問題,則引發錯誤或提出請求請求。最新版本的 Spring Boot 2.x 次要版本的每個修補程序版本都會出現一個新版本的 Spring Native。Spring Native 0.9.0 支持 Spring Boot 2.4.3,Spring Native 0.9.1 支持 Spring Boot 2.4.4,等等。雖然會發生一些重大變化,但我們將記錄遷移路徑。文檔質量達到了一個新的水平:參考文檔以 html 單頁或 pdf 的形式提供],並且我們發佈了本機提示的 Javadoc 公共 API。

3.start.spring.io

Stéphane Nicoll 在對 http://start.spring.io 和相關 IDE 的集成中,引入了對 Spring Native 的支持,所以現在這是探索如何使用 Spring 構建原生應用最簡單的方式。

添加 Spring Native 依賴後將會使用所需的依賴和插件自動配置 Maven 或 Gradle 項目,以便於支持原生。應用代碼本身沒有變化。

請檢查自動生成的 HELP.md 文件,該文件包含了有用的鏈接和文檔,同時它還能標記出來你是否選擇了一些在原生環境下不支持的依賴。

  1. 提前轉換

本機不同於 JVM:類路徑在構建時是固定的,例如需要反射或資源進行配置,沒有類延遲加載(可執行文件中附帶的所有內容在啓動時都加載到內存中),並且可以調用一些代碼在構建時。

爲了充分體現這些特性並允許 Spring 應用程序在本機上以最大的兼容性和最小的佔用空間運行,Brian Clozel 在此版本中引入了 Spring 提前(AOT)Maven 和 Gradle 插件,它們可以提前執行您的應用程序上的轉換。

第一種轉換旨在基於由驚人的 Andy Clement 設計和實現的推理引擎來生成 GraalVM 本機配置(反射,資源,代理,本機映像選項),該引擎瞭解什麼是 Spring 編程模型和基礎架構。例如,對於每個由註釋的類@Controller,一個條目將被添加到生成的reflect-config.json文件中。

無法推斷出某些本機配置,對於這些情況,我們引入了本機提示註釋(有關更多詳細信息,請參見 Javadoc),這使 Spring Native 可以比基於常規 JSON 的本機圖像配置更可維護,類型安全和靈活地支持本機配置。例如同春本地 MySQL 驅動支持提供線索,讓一代機映像正確的條目reflect-config.jsonresource-config.json以及native-image.properties如下:

@NativeHint(
    trigger = Driver.class,
    options = "--enable-all-security-services",
    types = @TypeHint(types = {
       FailoverConnectionUrl.class,
       FailoverDnsSrvConnectionUrl.class,
       // ...
    }), resources = {
    @ResourceHint(patterns = "com/mysql/cj/TlsSettings.properties"),
    @ResourceHint(patterns = "com.mysql.cj.LocalizedErrorMessages",
                      isBundle = true)
})
public class MySqlHints implements NativeConfiguration {}

NativeConfiguration和其他動態配置機制允許更強大的和動態的配置生成,但要注意它們的 API 將在即將到來的版本演變了很多。

Spring 開發人員還可以使用特定於應用程序的本機提示直接註釋其@Configuration@SpringBootApplication類,例如,Book通過諸如RestTemplate或的編程 API 將類序列化爲 JSON WebClient

@TypeHint(types = Book.class)
@SpringBootApplication
public class WebClientApplication {
    // ...
}

與提前轉換系統一起使用時,最後一種可能是最強大的機制是使用 Spring Boot 部署模型與 GraalVM native 結合引入的封閉世界假設自動生成本機優化代碼(源代碼和字節碼)的功能。圖像特徵。這裏的目標是通過使用本機圖像編譯器可以開箱即用地分析的代碼構造來限制所需的額外本機配置的數量,以提高兼容性,並通過減少反射所需的配置數量來減少佔用空間,資源或代理。一個具體的例子是各種形式的提前轉換spring.factories (Spring Boot 背後的擴展機制)到優化的程序設計版本,該版本不需要反射,並且可以在應用程序的上下文中過濾掉不必要的條目。

這只是 Spring AOT 的開始,我們打算向 [@Configuration功能配置中添加更強大的轉換,以通過提前分析來替換運行時反射,該提前分析將自動生成配置類,這些配置類將使用 lambda 和方法引用之類的程序化構造。這將使 GraalVM 本機圖像編譯器可以立即瞭解 Spring 配置,而無需任何反射配置或*.class資源。

要記住的一個關鍵點是,在使用 Spring Native 時,默認情況下在 JVM 上也會使用 AOT 生成的代碼,以允許您使用 JVM 允許的短反饋循環來行使 “本機友好的代碼路徑”。您的調試器和所有常規工具。

儘管 Spring AOT 轉換當前主要由本機需求驅動,但是其中許多不是本機特定的,並且可能其中一些可以提供優化以在 JVM 上運行 Spring Boot 應用程序。與此類主題一樣,重要的是數據驅動,以便我們測量效率和績效來決定我們的決策。

我們可能會改進 IDE 的集成,現在確保在 IDE 中運行應用程序之前,請先閱讀相關文檔以進行潛在的手動配置步驟,以更新生成的源代碼。

  1. 結論

Spring 戰略要本地化有兩個主要支柱。第一個是使 Spring 基礎結構適應本機,而無需對數百萬個現有的 Spring Boot 應用程序進行重大更改。其中包括我們在 Spring 頂級項目中所做的更改,以使其對本機友好,@NativeHint我們將在 Spring Native 中成熟的基礎架構(例如)和 Spring AOT 構建插件。

第二個支柱比 Spring 本身更廣泛,native 是一個具有與 JVM 不同的特性的平臺,但是 Java 生態系統需要儘可能地一致,以避免兩種非常不同的 Java 風格,這將難以維護。這就是爲什麼我們與 GraalVM 團隊進行深入合作以縮小這一差距的原因。在接下來的幾個月中,這項合作將專注於爲更廣泛的 JVM 生態系統改善本機測試和本機配置。

來源:spring.io/blog/2021/03/11/announcing-spring-native-beta

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/DCRJLVX3X3rqQIoDR8hteg