跳到主要内容

开发你的第一个 GraalVM 原生应用

DeepSeek V3 中英对照 Developing Your First GraalVM Native Application

构建 Spring Boot 原生镜像应用程序主要有两种方式:

提示

启动一个新的原生 Spring Boot 项目最简单的方法是访问 start.spring.io,添加 GraalVM Native Support 依赖项并生成项目。项目中的 HELP.md 文件将提供入门提示。

示例应用

我们需要一个示例应用程序,可以用来创建我们的原生镜像。为达到我们的目的,开发您的第一个 Spring Boot 应用程序 部分中介绍的简单的 "Hello World!" Web 应用程序就足够了。

回顾一下,我们的主要应用代码如下:

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);
}

}
java

本应用程序使用了 Spring MVC 和嵌入式 Tomcat,这两者均已通过测试并验证可与 GraalVM 原生镜像兼容。

使用 Buildpacks 构建原生镜像

Spring Boot 支持使用 Cloud Native Buildpacks (CNB) 与 Maven 和 Gradle 的集成,以及 Paketo Java Native Image buildpack 来构建包含原生可执行文件的 Docker 镜像。这意味着你只需输入一个命令,就能快速将合理的镜像推送到本地运行的 Docker 守护进程中。生成的镜像不包含 JVM,而是将原生镜像静态编译。这使得镜像更小。

备注

用于构建镜像的 CNB 构建器是 paketobuildpacks/builder-jammy-java-tiny:latest。它具有较小的占用空间和减少的攻击面。它不包含 shell,并且包含一组精简的系统库。如果需要镜像中有更多工具可用,请使用 paketobuildpacks/builder-jammy-base:latestpaketobuildpacks/builder-jammy-full:latest

系统要求

需要安装 Docker。更多详情请参阅 Get Docker。如果你在 Linux 上,请 配置以允许非 root 用户 使用 Docker。

备注

你可以运行 docker run hello-world(无需 sudo)来检查 Docker 守护进程是否按预期可达。有关更多详细信息,请查看 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>2.7.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.2</version>
</parent>
xml

此外,你还需要在 <build> <plugins> 部分添加以下内容:

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

spring-boot-starter-parent 声明了一个 native profile,该 profile 配置了创建原生镜像所需的执行步骤。你可以通过在命令行中使用 -P 标志来激活 profile。

提示

如果你不想使用 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
shell

使用 Gradle

当应用了 GraalVM Native Image 插件时,Spring Boot Gradle 插件会自动配置 AOT 任务。你应该检查你的 Gradle 构建是否包含一个 plugins 块,其中包含 org.graalvm.buildtools.native

只要应用了 org.graalvm.buildtools.native 插件,bootBuildImage 任务将生成原生镜像而不是 JVM 镜像。你可以通过以下命令运行该任务:

$ gradle bootBuildImage
shell

运行示例

一旦你运行了相应的构建命令,Docker 镜像就应该已经生成了。你可以使用 docker run 来启动你的应用程序:

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

你应该会看到类似以下的输出:

.   ____          _            __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v{version-spring-boot})
....... . . .
....... . . . (log output here)
....... . . .
........ Started MyApplication in 0.08 seconds (process running for 0.095)
shell
备注

启动时间因机器而异,但它应该比在 JVM 上运行的 Spring Boot 应用程序快得多。

如果你打开网页浏览器访问 [localhost:8080](http://localhost:8080),你应该会看到以下输出:

Hello World!
none

要优雅地退出应用程序,请按下 ctrl-c

使用原生构建工具构建原生镜像

如果你想在不使用 Docker 的情况下直接生成原生可执行文件,可以使用 GraalVM 原生构建工具(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
shell

通过检查 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)
shell

Windows

在 Windows 上,按照这些说明安装 GraalVMLiberica Native Image Kit 22.3 版本、Visual Studio 构建工具和 Windows SDK。由于 Windows 相关的命令行最大长度限制,请确保使用 x64 本机工具命令提示符而不是常规的 Windows 命令行来运行 Maven 或 Gradle 插件。

使用 Maven

buildpacks 支持 一样,你需要确保使用 spring-boot-starter-parent 以继承 native 配置文件,并且使用 org.graalvm.buildtools:native-maven-plugin 插件。

在激活 native 配置后,你可以调用 native:compile 目标来触发 native-image 编译:

$ mvn -Pnative native:compile
shell

原生镜像可执行文件可以在 target 目录中找到。

使用 Gradle

当将 Native Build Tools Gradle 插件应用到你的项目中时,Spring Boot Gradle 插件会自动触发 Spring AOT 引擎。任务依赖关系会自动配置,因此你只需运行标准的 nativeCompile 任务即可生成原生镜像:

$ gradle nativeCompile
shell

原生镜像可执行文件可以在 build/native/nativeCompile 目录中找到。

运行示例

此时,你的应用程序应该可以正常运行了。你现在可以通过直接运行来启动应用程序:

$ target/myproject
shell

您应该会看到类似以下的输出:

.   ____          _            __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.4.2)
....... . . .
....... . . . (log output here)
....... . . .
........ Started MyApplication in 0.08 seconds (process running for 0.095)
shell
备注

启动时间因机器而异,但应该比运行在 JVM 上的 Spring Boot 应用程序快得多。

如果你打开网页浏览器访问 [localhost:8080](http://localhost:8080),你应该会看到以下输出:

Hello World!
none

要优雅地退出应用程序,请按下 ctrl-c