使用 Spring Native 體驗 GraalVM:我在 Native Image-ville 的冒險

工程 | Josh Long | 2021 年 12 月 29 日 | ...

嗨,Spring 粉絲們!新年快樂! 我不敢相信我們這麼快就走到這一步了,但我們做到了。 去年非常忙碌,我最喜歡的事情之一就是有機會使用 Spring Native 來構建由 GraalVM 驅動、針對特定架構的 native image。

我們發布了 Spring Native 0.11,它非常棒,因為它具有一個全新的 AOT (ahead-of-time) 引擎,它完全重塑了我們將 Spring Boot 應用程式轉換為 GraalVM native image 的方式。 在過去的兩年中,我一直在使用 GraalVM,而這個新版本是 Spring Native 故事中一個巨大的、革命性的步驟,也是 Spring Framework 6 和 Spring Boot 3 之旅中的一大步,它們都將在 2022 年推出。

在過去的一個月中,我也一直在嘗試這個新版本。 Spring Native 非常適合 Spring 本身支持的許多用例,因此,對於大多數應用程式來說,我發現事情運作良好,無需任何更改。 也就是說,有些事情在 Spring Native 環境或任何 GraalVM 環境中,如果沒有一些幫助,將無法運作。 例如,如果告訴 GraalVM 你正在做什麼可能會讓它感到困惑(例如代理、序列化、資源加載等),那會有所幫助。 Spring Native 提供了一種機制 - 提示 (hints) - 您可以使用它來做到這一點。 這很容易。 但仍然必須完成。 因此,我一直在研究一些我認為可能需要幫助的專案,並嘗試讓它們運作。

MyBatis 和 Spring Native

我讓 Spring 和 MyBatis 良好地協同工作,並將其放入了一個範例分支中。 請參閱此部落格了解更多資訊。 讓 Spring 和 MyBatis Spring Boot 自動配置運作是一項挑戰。 我開始一點一點地重建自動配置,並設法建構了一個無可爭辯地不太有用、不太強大的 適用於 Spring Native 的 MyBatis Spring Boot 自動配置。 希望我們可以將其作為基礎,並弄清楚如何彌合差距,並讓提供的、支援的自動配置也能夠良好地運作。 我已經在與 MyBatis 團隊的一些成員討論是否要加入一些這方面的工作。 (祈禱!)。 透過這個概念驗證 Spring Boot 自動配置和 Spring Native 配置,您可以建立一個像這樣的 MyBatis SQL Mapper


@Mapper
public interface CityMapper {

	@Insert("INSERT INTO city (name, state, country) VALUES(#{name}, #{state}, #{country})")
	@Options(useGeneratedKeys = true, keyProperty = "id")
	void insert(City city);

	@Select("SELECT id, name, state, country FROM city ")
	Collection<City> findAll();
}

Spring Retrosocket 和 Spring Native

我也更新了 Spring Retrosocket 專案,使其能夠與 Spring Native 搭配使用。 Spring Retrosocket 是一個宣告式的 Feign- 或 Retrofit-like 客戶端,用於基於 RSocket 的服務。

@RSocketClient
interface GreetingsClient {

	@MessageMapping("hello")
	Mono<String> hello(Mono<String> name);
}

Kubernetes Java Client 和 Spring Native

然後,我將注意力轉向使 Kubernetes Java 客戶端在 Spring Native 和 GraalVM 環境中良好地運作。 如果您想為 Kubernetes 建構記憶體效率高的控制器和運算子,則 Kubernetes Java 客戶端至關重要。 我有沒有提到 GraalVM native image 非常 節省記憶體? 這取決於您在應用程式中所做的事情,但我的典型應用程式最終會佔用大約 40 到 55 MB 的 RAM(實際上,是 RSS)。 除了在短短幾十毫秒內啟動之外,這就是額外的好處。 官方的 Kubernetes-for-Java 客戶端有一個 Spring Boot 自動配置。 因此,我所要做的就是編寫 使這些應用程式在 Spring Native 和 GraalVM 環境中良好運作所需的簡單 Spring Native 配置我在這裡詳細解釋了它。 可以肯定地說,現在可以使用您最喜歡的開發框架,不僅可以建構出色的 Kubernetes 資源和控制器,還可以以低佔用的方式將它們部署到您組織的集群中。

Fabric8 和 Spring Native

說到 Kubernetes 客戶端,我也讓 RedHat 出色的 Fabric8.io Kubernetes 客戶端 能夠與 Spring Native 搭配使用。 我找到了一個可愛的範例運算子和自定義資源定義,然後我使用我的 Fabric8 Spring Native 提示 使其能夠運作。 這是一個功能更完善的範例,並且運作良好。 這是基於 Rohan Kanojia 的一個出色的範例,我發現並修改它以使用 Spring Boot 和 Spring Native。

這種方法很有前途! 在 Spring Native、官方 Kubernetes Java 客戶端和 Fabric8 客戶端之間,沒有理由不使用 Spring Boot 來建構您的下一個 Kubernetes 運算子。

Spring GraphQL 和 Spring Native

然後,我將注意力轉向 Spring GraphQl 和 Spring Native。 只要您覆蓋 GraphQlSourceBuilder 如何取得用於將架構提供給 GraphQL 端點引擎的 Spring Framework Resource 實例,Spring GraphQL 就能夠很好地運作。 它不像應該的那樣容易,但仍然只需要一個額外的 @Bean 或大約兩行程式碼即可使其運作。 很好。 當您使用 Spring GraphQL 並想要查詢 Spring GraphQL 架構的元模型時,麻煩就開始了。 當您使用 /graphiql/ 互動式控制台查詢資料時,擁有 GraphQL 元模型會很方便。 花了一些功夫,但我做到了。 我在 這篇文章中進一步解釋了這一點

有了這個,我可以部署一個像這樣的 GraphQL 控制器


@Controller
class CustomerGraphQlController {

	private final CustomerRepository repository;
 	
 	CustomerGraphQlController(CustomerRepository repository) {
 		this.repository = repository ;
 	} 

	@QueryMapping
	Flux<Customer> customers() {
		return this.repository.findAll();
	}
}

record Customer(@Id Integer id, String name) {
}

...它使用以下架構

type Query {
    customers : [Customer]
}
type Customer {
    id: ID
    name :String
}

然後在 https://127.0.0.1:8080/graphiql/ 開啟範例,並發出以下查詢

query {
 customers { id, name }
}

並獲得我所期望的結果!

其他

我也一直在處理許多其他我想讓 Spring Native 運作的事情。 因此,這是 CommonMark(Java 中的 Markdown 解析器) 的 Spring Native 配置。

以下是我為了使 Apache Lucene 在 Spring Native 專案中運作而必須添加的各種類別。 當然,這個範例更為複雜,並且使用 GraalVM 替換 (substitutions) 和典型的 Spring Native 配置。 但它可以運作,而且運作良好!

哦,我是否提到我與 Ronald Dehuysser 合作,以使 Jobrunr(一個分散式任務排程引擎)在具有 Spring Native 的 GraalVM 環境中運作? 因為我確實這樣做了,結果非常棒

我只是在過去幾週內完成了所有這些工作:可能性是無限的,我迫不及待地想看到越來越多的 Springdom 廣泛世界湧現 GraalVM 整合。

取得 Spring 電子報

隨時掌握 Spring 電子報的最新資訊

訂閱

領先一步

VMware 提供培訓和認證,助您加速進展。

了解更多

取得支援

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

了解更多

近期活動

查看 Spring 社群中所有即將舉行的活動。

查看全部