开发您的第一个 GraalVM 原生应用程序
现在我们已经对 GraalVM Native Images 和 Spring 的提前编译引擎有了很好的了解,我们可以看看如何创建一个应用程序。
构建 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!”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);
}
}
此应用程序使用 Spring MVC 和嵌入式 Tomcat,两者都经过测试和验证,可以与 GraalVM 原生镜像一起使用。
使用 Buildpacks 构建原生镜像
Spring Boot 直接为 Maven 和 Gradle 包含了对原生镜像的 buildpack 支持。这意味着您只需键入一个命令,就可以快速将一个合理的镜像放入您本地运行的 Docker 守护进程中。生成的镜像不包含 JVM,而是静态编译了原生镜像。这会导致更小的镜像。
用于镜像的构建器是 paketobuildpacks/builder-jammy-tiny:latest 。它占用的空间很小,攻击面也更小,但您也可以使用 paketobuildpacks/builder-jammy-base:latest 或 paketobuildpacks/builder-jammy-full:latest ,如果需要,可以在镜像中使用更多工具。
|
系统要求
需要安装 Docker。有关详细信息,请参阅 获取 Docker。如果您使用的是 Linux,请 配置它以允许非 root 用户。
您可以运行 docker run hello-world (无需 sudo )以检查 Docker 守护进程是否按预期可达。有关详细信息,请查看 Maven 或 Gradle Spring Boot 插件文档。
|
在 macOS 上,建议将分配给 Docker 的内存增加到至少 8GB ,并可能添加更多 CPU。有关详细信息,请参阅此 Stack Overflow 答案。在 Microsoft Windows 上,请确保启用 Docker WSL 2 后端 以获得更好的性能。
|
使用 Maven
要使用 Maven 构建本机镜像容器,您应该确保您的 pom.xml
文件使用 spring-boot-starter-parent
和 org.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 目标配置执行。
|
要构建镜像,您可以运行 spring-boot:build-image
目标,并激活 native
配置文件
$ mvn -Pnative spring-boot:build-image
使用 Gradle
当应用 GraalVM Native Image 插件时,Spring Boot Gradle 插件会自动配置 AOT 任务。您应该检查您的 Gradle 构建是否包含一个包含 org.graalvm.buildtools.native
的 plugins
块。
只要应用了 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 应用程序快得多。 |
如果您在 Web 浏览器中打开 localhost:8080
,您应该看到以下输出
Hello World!
要优雅地退出应用程序,请按 ctrl-c
。
使用 Native Build Tools 构建 Native Image
如果您想直接生成本地可执行文件而不使用 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 的 GraalVM 或 Liberica 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 应用程序快得多。 |
如果您在 Web 浏览器中打开 localhost:8080
,您应该看到以下输出
Hello World!
要优雅地退出应用程序,请按 ctrl-c
。