将红帽构建的 Quarkus 应用程序编译到原生可执行文件
使开源包含更多 复制链接链接已复制到粘贴板!
红帽致力于替换我们的代码、文档和 Web 属性中有问题的语言。我们从这四个术语开始:master、slave、黑名单和白名单。由于此项工作十分艰巨,这些更改将在即将推出的几个发行版本中逐步实施。详情请查看 CTO Chris Wright 的信息。
第 1 章 将红帽构建的 Quarkus 应用程序编译到原生可执行文件 复制链接链接已复制到粘贴板!
作为应用程序开发人员,您可以使用红帽构建的 Quarkus 3.2 创建使用 OpenShift Container Platform 和无服务器环境中运行的 Java 编写的微服务。Quarkus 应用程序可以作为常规 Java 应用程序(在 Java 虚拟机之上)运行,或者编译到原生可执行文件中。编译到原生可执行文件的应用程序具有比 Java 对应部分小的内存占用和更快的启动时间。
本指南介绍了如何将红帽构建的 Quarkus 3.2 入门项目编译到原生可执行文件中,以及如何配置和测试原生可执行文件。您需要您之前在 红帽构建的 Quarkus 中创建 的应用程序。
使用 Red Hat build of Quarkus 构建原生可执行文件涵盖了:
- 使用 Podman 或 Docker 等容器运行时(如 Podman 或 Docker)通过单个命令构建原生可执行文件
- 使用生成的原生可执行文件创建自定义容器镜像
- 使用 OpenShift Container Platform Docker 构建策略创建容器镜像
- 将 Quarkus 原生应用程序部署到 OpenShift Container Platform
- 配置原生可执行文件
- 测试原生可执行文件
先决条件
安装了 OpenJDK 17,并且设置了
JAVA_HOME环境变量,以指定 Java SDK 的位置。- 登录到红帽客户门户网站,从 Software Downloads 页面下载红帽构建的 OpenJDK。
- 一个兼容开放容器项目(OCI)的容器运行时,如 Podman 或 Docker。
已完成的 Quarkus 入门项目。
- 要了解如何构建 Quarkus Getting Started 项目,请参阅开始使用 Quarkus。
-
或者,您可以下载 Quarkus Quickstart 归档 或克隆
Quarkus QuickstartsGit 存储库。示例项目处于getting-started目录中。
1.1. 生成原生可执行文件 复制链接链接已复制到粘贴板!
原生二进制文件是创建在特定操作系统和 CPU 架构上运行的可执行文件。
以下列表概述了原生可执行文件的一些示例:
- Linux AMD 64 位的 ELF 二进制文件
- Windows AMD 64 位的 EXE 二进制文件
- ARM 64 位的 ELF 二进制文件
构建原生可执行文件时,您的应用程序和依赖项(包括 JVM)被打包到一个文件中。应用程序的原生可执行文件包含以下项目:
- 编译的应用程序代码。
- 所需的 Java 库。
- 用于改进应用程序启动时间和最小磁盘和内存占用量的 Java 虚拟机(JVM)的减少版本,它也是为应用程序代码及其依赖项量身定制的。
要从 Quarkus 应用生成原生可执行文件,您可以选择容器内构建或 local-host 构建。下表解释您可以使用的不同构建选项:
| 构建选项 | Requires | 使用 | 结果 | 优点 |
|---|---|---|---|---|
| in-container build - Supported | 容器运行时,如 Podman 或 Docker |
默认 | 使用主机的 CPU 架构进行 Linux 64 位可执行文件 | GraalVM 不需要在本地设置,从而使 CI 管道 更有效地运行 |
| local-host build - 仅支持上游 | GraalVM 或 Mandrel 的本地安装 |
其本地安装作为 | 具有与执行构建的机器相同的操作系统和 CPU 架构的可执行文件 | 不允许或不想使用 Docker 或 Podman 等工具的开发人员的替代方案。总体而言,它比容器内构建方法更快。 |
- Red Hat build of Quarkus 3.2 仅支持使用基于 Java 17 的 红帽构建的 Quarkus 原生构建器镜像 构建原生 Linux 可执行文件,该镜像是 Mandrel 的产品化分发。虽然其他镜像在社区中可用,但产品不支持它们,因此您不应该将其用于您希望红帽提供支持的生产构建。
- 其源基于 Java 11 编写的应用程序,没有 Java 12 - 17 的功能,仍可使用 Java 17 的 Mandrel 23.0 基础镜像编译应用程序的原生可执行文件。
- 使用红帽构建的 Quarkus 不支持使用 Oracle GraalVM 社区版(CE)、Mael 社区版本或任何其他 GraalVM 发行版构建原生可执行文件。
1.1.1. 使用 in-container 构建生成原生可执行文件 复制链接链接已复制到粘贴板!
要创建原生可执行文件并运行原生镜像测试,请使用由红帽构建的 Quarkus 提供的 原生 配置集进行容器内构建。
先决条件
- podman 或 Docker 已安装。
- 容器可以访问至少 8GB 内存。
流程
打开 Getting Started project
pom.xml文件,并验证项目是否包含native配置集:Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用以下方法之一构建原生可执行文件:
使用 Maven:
对于 Docker:
./mvnw package -Dnative -Dquarkus.native.container-build=true
./mvnw package -Dnative -Dquarkus.native.container-build=trueCopy to Clipboard Copied! Toggle word wrap Toggle overflow 对于 Podman:
./mvnw package -Dnative -Dquarkus.native.container-build=true -Dquarkus.native.container-runtime=podman
./mvnw package -Dnative -Dquarkus.native.container-build=true -Dquarkus.native.container-runtime=podmanCopy to Clipboard Copied! Toggle word wrap Toggle overflow
使用 Quarkus CLI:
对于 Docker:
quarkus build --native -Dquarkus.native.container-build=true
quarkus build --native -Dquarkus.native.container-build=trueCopy to Clipboard Copied! Toggle word wrap Toggle overflow 对于 Podman:
quarkus build --native -Dquarkus.native.container-build=true -Dquarkus.native.container-runtime=podman
quarkus build --native -Dquarkus.native.container-build=true -Dquarkus.native.container-runtime=podmanCopy to Clipboard Copied! Toggle word wrap Toggle overflow 步骤结果
这些命令在目标目录中创建一个
*-runner二进制文件,其中适用以下内容:-
*-runner文件是由 Quarkus 生成的构建原生二进制文件。 目标目录是一个目录,Maven 会在构建 Maven 应用程序时创建该目录。重要将 Quarkus 应用程序编译到原生可执行文件会在分析和优化过程中消耗大量内存。您可以通过设置
quarkus.native.native-image-xmx配置属性来限制原生编译过程中使用的内存量。设置低内存限值可能会增加构建时间。
要运行原生可执行文件,请输入以下命令:
./target/*-runner
./target/*-runnerCopy to Clipboard Copied! Toggle word wrap Toggle overflow
其他资源
1.1.2. 使用 local-host 构建生成原生可执行文件 复制链接链接已复制到粘贴板!
如果您不使用 Docker 或 Podman,请使用 Quarkus local-host build 选项来创建和运行原生可执行文件。
使用本地主机构建方法比使用容器更快,并适用于使用 Linux 操作系统的机器。
红帽构建的 Quarkus 不支持在生产环境中使用以下步骤。只有在 Docker 或 Podman 不可用时,才使用这个方法测试或作为备份方法。
先决条件
Mandrel 或 GraalVm 的本地安装,根据 构建原生可执行文件 指南进行了正确配置。
-
另外,对于 GraalVM 安装,还必须安装
native-image。
-
另外,对于 GraalVM 安装,还必须安装
流程
对于 GraalVM 或 Mandrel,使用以下方法之一构建原生可执行文件:
使用 Maven:
./mvnw package -Dnative
./mvnw package -DnativeCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用 Quarkus CLI:
quarkus build --native
quarkus build --nativeCopy to Clipboard Copied! Toggle word wrap Toggle overflow 步骤结果
这些命令在目标目录中创建一个
*-runner二进制文件,其中适用以下内容:-
*-runner文件是由 Quarkus 生成的构建原生二进制文件。 目标目录是一个目录,Maven 会在构建 Maven 应用程序时创建该目录。注意构建原生可执行文件时,会启用
prod配置集,除非在quarkus.profile属性中修改了。
-
运行原生可执行文件:
./target/*-runner
./target/*-runnerCopy to Clipboard Copied! Toggle word wrap Toggle overflow
其他资源
如需更多信息,请参阅 Quarkus 社区中的"构建原生可执行文件"指南中的 Producing a native executable 部分。
1.2. 创建自定义容器镜像 复制链接链接已复制到粘贴板!
您可以使用以下方法之一从 Quarkus 应用程序创建容器镜像:
- 手动创建容器
- 使用 OpenShift Container Platform Docker 构建创建容器
将 Quarkus 应用程序编译到原生可执行文件会在分析和优化过程中消耗大量内存。您可以通过设置 quarkus.native.native-image-xmx 配置属性来限制原生编译过程中使用的内存量。设置低内存限值可能会增加构建时间。
1.2.1. 手动创建容器 复制链接链接已复制到粘贴板!
本节演示了如何为 Linux AMD64 使用应用程序手动创建容器镜像。当您使用 Quarkus Native 容器生成原生镜像时,原生镜像会创建一个以 Linux AMD64 为目标的可执行文件。如果您的主机操作系统与 Linux AMD64 不同,则无法直接运行二进制文件,您需要手动创建容器。
您的 Quarkus Getting Started 项目在 src/main/docker 目录中包含一个 Dockerfile.native,其内容如下:
通用基础镜像(UBI)
以下列表显示了可用于 Dockerfile 的合适镜像。
Red Hat Universal Base Image 8 (UBI8)。此基础镜像旨在设计并设计成为所有容器化应用程序、中间件和实用程序的基础层。
registry.access.redhat.com/ubi8/ubi:8.8
registry.access.redhat.com/ubi8/ubi:8.8Copy to Clipboard Copied! Toggle word wrap Toggle overflow Red Hat Universal Base Image 8 Minimal (UBI8-minimal)。使用 microdnf 作为软件包管理器的精简版 UBI8 镜像。
registry.access.redhat.com/ubi8/ubi-minimal:8.8
registry.access.redhat.com/ubi8/ubi-minimal:8.8Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 所有红帽基础镜像都可在容器镜像目录站点中找到。https://catalog.redhat.com/software/containers/search?q=UBI&p=1
流程
使用以下方法之一构建原生 Linux 可执行文件:
docker:
./mvnw package -Dnative -Dquarkus.native.container-build=true
./mvnw package -Dnative -Dquarkus.native.container-build=trueCopy to Clipboard Copied! Toggle word wrap Toggle overflow Podman:
./mvnw package -Dnative -Dquarkus.native.container-build=true -Dquarkus.native.container-runtime=podman
./mvnw package -Dnative -Dquarkus.native.container-build=true -Dquarkus.native.container-runtime=podmanCopy to Clipboard Copied! Toggle word wrap Toggle overflow
使用以下方法之一构建容器镜像:
docker:
docker build -f src/main/docker/Dockerfile.native -t quarkus-quickstart/getting-started .
docker build -f src/main/docker/Dockerfile.native -t quarkus-quickstart/getting-started .Copy to Clipboard Copied! Toggle word wrap Toggle overflow Podman
podman build -f src/main/docker/Dockerfile.native -t quarkus-quickstart/getting-started .
podman build -f src/main/docker/Dockerfile.native -t quarkus-quickstart/getting-started .Copy to Clipboard Copied! Toggle word wrap Toggle overflow
使用以下方法之一运行容器:
docker:
docker run -i --rm -p 8080:8080 quarkus-quickstart/getting-started
docker run -i --rm -p 8080:8080 quarkus-quickstart/getting-startedCopy to Clipboard Copied! Toggle word wrap Toggle overflow Podman:
podman run -i --rm -p 8080:8080 quarkus-quickstart/getting-started
podman run -i --rm -p 8080:8080 quarkus-quickstart/getting-startedCopy to Clipboard Copied! Toggle word wrap Toggle overflow
1.2.2. 使用 OpenShift Docker 构建创建容器 复制链接链接已复制到粘贴板!
您可以使用 OpenShift Container Platform Docker 构建策略为 Quarkus 应用程序创建容器镜像。此策略使用集群中的构建配置创建容器镜像。
先决条件
-
您可以访问 OpenShift Container Platform 集群并安装
oc工具的最新版本。有关安装oc的详情,请参考 安装和配置 OpenShift Container Platform 集群指南中的安装 CLI。 - OpenShift Container Platform API 端点的 URL。
流程
登录到 OpenShift CLI:
oc login -u <username_url>
oc login -u <username_url>Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在 OpenShift 中创建一个新项目:
oc new-project <project_name>
oc new-project <project_name>Copy to Clipboard Copied! Toggle word wrap Toggle overflow 根据
src/main/docker/Dockerfile.native文件创建构建配置:cat src/main/docker/Dockerfile.native | oc new-build --name <build_name> --strategy=docker --dockerfile -
cat src/main/docker/Dockerfile.native | oc new-build --name <build_name> --strategy=docker --dockerfile -Copy to Clipboard Copied! Toggle word wrap Toggle overflow 构建项目:
oc start-build <build_name> --from-dir .
oc start-build <build_name> --from-dir .Copy to Clipboard Copied! Toggle word wrap Toggle overflow 将项目部署到 OpenShift Container Platform:
oc new-app <build_name>
oc new-app <build_name>Copy to Clipboard Copied! Toggle word wrap Toggle overflow 公开服务:
oc expose svc/<build_name>
oc expose svc/<build_name>Copy to Clipboard Copied! Toggle word wrap Toggle overflow
1.3. 原生可执行配置属性 复制链接链接已复制到粘贴板!
配置属性定义如何生成原生可执行文件。您可以使用 application.properties 文件配置 Quarkus 应用程序。
配置属性
下表列出了您可以设置的配置属性来定义如何生成原生可执行文件:
| 属性 | 描述 | 类型 | default |
|
|
如果启用了 debug 并生成调试符号,则会在单独的 | 布尔值 | false |
|
| 以逗号分隔的 glob 列表,以匹配不应添加到原生镜像的资源路径。 | 字符串列表 | |
|
| 传递给构建过程的额外参数。 | 字符串列表 | |
|
|
启用 HTTP URL 处理程序。这可让您为 HTTP URL 执行 | 布尔值 |
|
|
|
启用 HTTPS URL 处理程序。这可让您为 HTTPS URL 执行 | 布尔值 |
|
|
| 将所有安全服务添加到原生镜像。 | 布尔值 |
|
|
| 将所有字符集添加到原生镜像。这会增加镜像大小。 | 布尔值 |
|
|
| 包含 GraalVM 分发的路径。 | string |
|
|
| 包含 JDK 的路径。 |
| |
|
| 用于生成原生镜像的最大 Java 堆。 | string | |
|
| 在运行原生镜像构建前,等待调试器附加到构建过程。对于熟悉 GraalVM 内部的用户,这是一个高级选项。 | 布尔值 |
|
|
|
如果 | 布尔值 |
|
|
| 重启原生镜像服务器。 | 布尔值 |
|
|
| 启用隔离以提高内存管理。 | 布尔值 |
|
|
| 如果原生镜像失败,则创建基于 JVM 的回退镜像。 | 布尔值 |
|
|
| 使用原生镜像服务器。这可以加快编译速度,但可能会导致由于缓存无效问题而丢失更改。 | 布尔值 |
|
|
|
自动注册所有 | 布尔值 |
|
|
| 转储所有代理的字节代码以进行检查。 | 布尔值 |
|
|
| 使用容器运行时的构建。默认使用 Docker。 | 布尔值 |
|
|
| 构建镜像的 docker 镜像。 | string |
|
|
| 用于构建镜像的容器运行时。例如,Docker。 | string | |
|
| 传递给容器运行时的选项。 | 字符串列表 | |
|
| 在镜像中启用虚拟机内省。 | 布尔值 |
|
|
| 在镜像中启用完整的堆栈跟踪。 | 布尔值 |
|
|
| 生成关于调用路径和包含的软件包、类或方法的报告。 | 布尔值 |
|
|
| 报告完整堆栈追踪的异常。 | 布尔值 |
|
|
| 在运行时报告错误。如果您使用不支持的功能,这可能会导致应用程序在运行时失败。 | 布尔值 |
|
|
|
以逗号分隔的 glob 列表,以匹配应添加到原生镜像的资源路径。在所有平台上使用斜杠( | 字符串列表 | |
|
|
启用调试并在单独的 | 布尔值 |
|
支持的 glob 功能
下表列出了支持的 glob 功能和描述:
| 字符 | 功能描述 |
|
|
匹配不包含斜杠( |
|
|
匹配可能包含斜杠( |
|
| 匹配一个字符,但不匹配斜杠。 |
|
| 匹配 bracket 中指定的一个字符,但不匹配斜杠。 |
|
| 匹配 bracket 中指定的范围中的一个字符,但不匹配斜杠。 |
|
| 匹配括号中未指定的字符; 不匹配斜杠。 |
|
| 匹配 bracket 中指定的范围之外的一个字符; 不匹配斜杠。 |
|
| 匹配以逗号分开的任何 alternating 令牌;令牌可以包含通配符、嵌套更改和范围。 |
|
|
转义字符。有三个级别的转义程序: |
1.3.1. 为红帽构建的 Quarkus 原生编译配置内存消耗 复制链接链接已复制到粘贴板!
将红帽构建的 Quarkus 应用程序编译到原生可执行文件会在分析和优化过程中消耗大量内存。您可以通过设置 quarkus.native.native-image-xmx 配置属性来限制原生编译过程中使用的内存量。设置低内存限值可能会增加构建时间。
流程
使用以下方法之一为
quarkus.native.native-image-xmx属性设置值,以限制原生镜像构建期间的内存消耗:使用
application.properties文件:quarkus.native.native-image-xmx=<maximum_memory>
quarkus.native.native-image-xmx=<maximum_memory>Copy to Clipboard Copied! Toggle word wrap Toggle overflow 设置系统属性:
mvn package -Dnative -Dquarkus.native.container-build=true -Dquarkus.native.native-image-xmx=<maximum_memory>
mvn package -Dnative -Dquarkus.native.container-build=true -Dquarkus.native.native-image-xmx=<maximum_memory>Copy to Clipboard Copied! Toggle word wrap Toggle overflow 此命令使用 Docker 构建原生可执行文件。要使用 Podman,请添加
-Dquarkus.native.container-runtime=podman参数。
例如,要将内存限制设置为 6 GB,请输入 quarkus.native.native-image-xmx=6g。该值必须是 1024 的倍数,大于 2MB。附加字母 m 或 M 表示兆字节,或 G 或 G 表示 GB。
1.4. 测试原生可执行文件 复制链接链接已复制到粘贴板!
以原生模式测试应用,以测试原生可执行文件的功能。使用 @QuarkusIntegrationTest 注释来构建原生可执行文件,并根据 HTTP 端点运行测试。
以下示例演示了如何使用本地安装 GraalVM 或 Mandrel 测试原生可执行文件。开始之前,请考虑以下点:
- Red Hat build of Quarkus 不支持此场景,如 Producing a native executable 所述。
- 您在此处测试的原生可执行文件必须与主机的操作系统和架构匹配。因此,这个过程不适用于 macOS 或 in-container 构建。
流程
打开
pom.xml文件,并验证build部分是否具有以下元素:Copy to Clipboard Copied! Toggle word wrap Toggle overflow -
Maven Failsafe 插件(
maven-failsafe-plugin)运行集成测试,并指示生成的原生可执行文件的位置。
-
Maven Failsafe 插件(
打开
src/test/java/org/acme/GreetingResourceIT.java文件,并验证该文件是否包含以下内容:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
运行测试:
./mvnw verify -Dnative
./mvnw verify -DnativeCopy to Clipboard Copied! Toggle word wrap Toggle overflow 以下示例显示了这个命令的输出:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 注意Quarkus 在自动失败原生测试前等待 60 秒启动原生镜像。您可以通过配置
quarkus.test.wait-time系统属性来更改此持续时间。您可以使用以下命令扩展等待时间,其中 <
duration> 是等待时间(以秒为单位):./mvnw verify -Dnative -Dquarkus.test.wait-time=<duration>
./mvnw verify -Dnative -Dquarkus.test.wait-time=<duration>Copy to Clipboard Copied! Toggle word wrap Toggle overflow 注意-
除非在
quarkus.test.native-image-profile属性中修改了,否则会使用prod配置集运行原生测试。
-
除非在
1.4.1. 当作为原生可执行文件运行时排除测试 复制链接链接已复制到粘贴板!
当您针对原生可执行文件运行测试时,您只能运行黑框测试,例如与应用的 HTTP 端点交互。
黑色框 指的是产品或程序的隐藏的内部工作,如黑色测试。
由于测试没有原生运行,所以无法在 JVM 上运行测试时链接到您的应用代码。因此,在您的原生测试中,您无法注入 Bean。
您可以在 JVM 和原生执行间共享测试类,并使用 @DisabledOnNativeImage 注释排除某些测试,以便仅在 JVM 上运行测试。
1.4.2. 测试现有的原生可执行文件 复制链接链接已复制到粘贴板!
通过使用 Failsafe Maven 插件,您可以针对现有的可执行构建进行测试。您可以在二进制代码构建后,以阶段方式运行多组测试。
要测试您使用 Quarkus 生成的原生可执行文件,请使用可用的 Maven 命令。使用命令行没有等同的 Quarkus CLI 命令来完成此任务。
流程
针对已构建的原生可执行文件运行测试:
./mvnw test-compile failsafe:integration-test
./mvnw test-compile failsafe:integration-testCopy to Clipboard Copied! Toggle word wrap Toggle overflow 此命令使用
FailsafeMaven 插件针对现有的原生镜像运行测试。另外,您可以使用以下命令指定原生可执行文件的路径,其中 <
path>是原生镜像路径:./mvnw test-compile failsafe:integration-test -Dnative.image.path=<path>
./mvnw test-compile failsafe:integration-test -Dnative.image.path=<path>Copy to Clipboard Copied! Toggle word wrap Toggle overflow