開發您的第一個 GraalVM 原生應用程式 (開發您的第一個 GraalVM 原生應用程式)

既然我們已經大致了解了 GraalVM 原生映像檔以及 Spring 預先 (AOT) 引擎的運作方式,現在我們可以看看如何建立應用程式。

建立 Spring Boot 原生映像檔應用程式主要有兩種方法

  • 使用 Spring Boot 對 Cloud Native Buildpacks 的支援來產生包含原生執行檔的輕量級容器。

  • 使用 GraalVM Native Build Tools 來產生原生執行檔。

開始新的原生 Spring Boot 專案最簡單的方法是前往 start.spring.io,新增「GraalVM Native Support」依賴項,然後產生專案。內含的 HELP.md 檔案將提供入門提示。

範例應用程式

我們需要一個範例應用程式來建立原生映像檔。就我們的目的而言,「開發您的第一個 Spring Boot 應用程式」一節中介紹的簡單「Hello World!」網路應用程式就足夠了。

回顧一下,我們主要的應用程式程式碼如下所示

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@SpringBootApplication
public class MyApplication {

	@RequestMapping("/")
	String home() {
		return "Hello World!";
	}

	public static void main(String[] args) {
		SpringApplication.run(MyApplication.class, args);
	}

}

此應用程式使用 Spring MVC 和嵌入式 Tomcat,兩者都經過測試和驗證,可與 GraalVM 原生映像檔搭配使用。

使用 Buildpacks 建置原生映像檔

Spring Boot 直接包含了針對 Maven 和 Gradle 的原生映像檔 buildpack 支援。這表示您只需輸入單一指令,即可快速將合理的映像檔放入您本機執行的 Docker daemon 中。產生的映像檔不包含 JVM,而是靜態編譯原生映像檔。這會產生較小的映像檔。

用於映像檔的建置器是 paketobuildpacks/builder-jammy-tiny:latest。它佔用空間小,攻擊面也較小,但如果需要,您也可以使用 paketobuildpacks/builder-jammy-base:latestpaketobuildpacks/builder-jammy-full:latest,以便在映像檔中使用更多工具。

系統需求

必須安裝 Docker。詳情請參閱 取得 Docker。如果您使用的是 Linux 系統,請將其設定為允許非 root 使用者

您可以執行 docker run hello-world(不使用 sudo)來檢查 Docker daemon 是否如預期般可連線。查看 MavenGradle Spring Boot 外掛程式文件以取得更多詳細資訊。
在 macOS 上,建議將分配給 Docker 的記憶體增加到至少 8GB,並且可能也需要增加 CPU 核心數。詳情請參閱這個 Stack Overflow 答案。在 Microsoft Windows 上,請務必啟用 Docker WSL 2 後端 以獲得更好的效能。

使用 Maven

要使用 Maven 建置原生映像容器,您應該確保您的 pom.xml 檔案使用 spring-boot-starter-parentorg.graalvm.buildtools:native-maven-plugin。您的 <parent> 區段應該如下所示

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>3.3.0</version>
</parent>

此外,您應該在 <build> <plugins> 區段中加入以下內容

<plugin>
	<groupId>org.graalvm.buildtools</groupId>
	<artifactId>native-maven-plugin</artifactId>
</plugin>

spring-boot-starter-parent 宣告了一個 native 設定檔,用於設定建立原生映像所需的執行項目。您可以使用命令列上的 -P 旗標來啟用設定檔。

如果您不想使用 spring-boot-starter-parent,則需要為 Spring Boot 外掛程式的 process-aot 目標和 Native Build Tools 外掛程式的 add-reachability-metadata 目標設定執行項目。

要建置映像,您可以在啟用 native 設定檔的情況下執行 spring-boot:build-image 目標

$ mvn -Pnative spring-boot:build-image

使用 Gradle

當套用 GraalVM Native Image 外掛程式時,Spring Boot Gradle 外掛程式會自動設定 AOT 任務。您應該檢查您的 Gradle 建置檔是否包含一個包含 org.graalvm.buildtools.nativeplugins 區塊。

只要套用了 org.graalvm.buildtools.native 外掛程式,bootBuildImage 任務就會產生原生映像,而不是 JVM 映像。您可以使用以下指令執行該任務

$ gradle bootBuildImage

執行範例

執行適當的建置命令後,應該會有一個 Docker 映像可用。您可以使用 docker run 啟動您的應用程式

$ docker run --rm -p 8080:8080 docker.io/library/myproject:0.0.1-SNAPSHOT

您應該會看到類似以下的輸出

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::  (v{version-spring-boot})
....... . . .
....... . . . (log output here)
....... . . .
........ Started MyApplication in 0.08 seconds (process running for 0.095)
啟動時間因機器而異,但它應該比在 JVM 上執行的 Spring Boot 應用程式快得多。

如果您在網頁瀏覽器中開啟 localhost:8080,您應該會看到以下輸出

Hello World!

要正常結束應用程式,請按 ctrl-c

使用 Native Build Tools 建置原生映像

如果您想直接產生原生執行檔而不使用 Docker,您可以使用 GraalVM Native Build Tools。Native Build Tools 是 GraalVM 為 Maven 和 Gradle 提供的外掛程式。您可以使用它們來執行各種 GraalVM 任務,包括產生原生映像。

先決條件

要使用 Native Build Tools 建置原生映像,您的機器上需要有 GraalVM 發行版。您可以在 Liberica Native Image Kit 頁面上手動下載,或者您可以使用 SDKMAN! 等下載管理器。

Linux 和 macOS

要在 macOS 或 Linux 上安裝原生映像編譯器,我們建議使用 SDKMAN!。從 sdkman.io 取得 SDKMAN! 並使用以下命令安裝 Liberica GraalVM 發行版

$ sdk install java 22.3.r17-nik
$ sdk use java 22.3.r17-nik

透過檢查 java -version 的輸出驗證是否已設定正確的版本

$ java -version
openjdk version "17.0.5" 2022-10-18 LTS
OpenJDK Runtime Environment GraalVM 22.3.0 (build 17.0.5+8-LTS)
OpenJDK 64-Bit Server VM GraalVM 22.3.0 (build 17.0.5+8-LTS, mixed mode)

Windows

在 Windows 上,請按照這些指示安裝 22.3 版的 GraalVMLiberica Native Image Kit、Visual Studio Build Tools 和 Windows SDK。由於Windows 命令列的最大長度限制,請務必使用 x64 Native Tools Command Prompt,而不是一般的 Windows 命令列來執行 Maven 或 Gradle 外掛程式。

使用 Maven

如同建置包支援,您需要確保使用 spring-boot-starter-parent 來繼承 native 設定檔,並且使用 org.graalvm.buildtools:native-maven-plugin 外掛程式。

啟用 native 設定檔後,您可以呼叫 native:compile 指令來觸發 native-image 編譯。

$ mvn -Pnative native:compile

原生映像執行檔位於 target 目錄中。

使用 Gradle

當 Native Build Tools Gradle 外掛程式套用到您的專案時,Spring Boot Gradle 外掛程式會自動觸發 Spring AOT 引擎。工作相依性會自動設定,因此您只需執行標準的 nativeCompile 工作即可產生原生映像。

$ gradle nativeCompile

原生映像執行檔位於 build/native/nativeCompile 目錄中。

執行範例

此時,您的應用程式應該可以運作。您現在可以直接執行應用程式來啟動它。

  • Maven

  • Gradle

$ target/myproject
$ build/native/nativeCompile/myproject

您應該會看到類似以下的輸出

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::  (v3.3.0)
....... . . .
....... . . . (log output here)
....... . . .
........ Started MyApplication in 0.08 seconds (process running for 0.095)
啟動時間因機器而異,但它應該比在 JVM 上執行的 Spring Boot 應用程式快得多。

如果您在網頁瀏覽器中開啟 localhost:8080,您應該會看到以下輸出

Hello World!

要正常結束應用程式,請按 ctrl-c