将 Quarkus 应用程序编译到原生可执行文件
指南
摘要
前言 复制链接链接已复制到粘贴板!
作为应用程序开发人员,您可以使用 Red Hat build of Quarkus 创建在 OpenShift 和无服务器环境中运行的 Java 中编写的微服务。编译到原生可执行文件的应用程序具有小内存占用和启动时间。
本指南介绍了如何将 Quarkus 入门项目编译为原生可执行文件,以及如何配置和测试原生可执行文件。您需要在 Getting started with Quarkus 中创建的应用程序。
使用红帽构建的 Quarkus 构建原生可执行文件涵盖了:
- 使用 Podman 或 Docker 等容器运行时通过单个命令构建原生可执行文件
- 使用生成的原生可执行文件创建自定义容器镜像
- 使用 OpenShift Docker 构建策略创建容器镜像
- 将 Quarkus 原生应用程序部署到 OpenShift
- 配置原生可执行文件
- 测试原生可执行文件
先决条件
安装 OpenJDK(JDK)11,将
JAVA_HOME环境变量设置为指定 Java SDK 的位置。- 登录红帽客户门户网站,从 Software Downloads 页面下载 Open JDK 的 Red Hat build。
- OCI(开放容器项目)兼容的容器运行时,如 Podman 或 Docker。
完成的 Quarkus 快速入门项目。
- 要了解如何构建 Quarkus 快速入门项目,请参阅 使用 Quarkus 入门。
-
另外,您可以下载 Quarkus Quickstart 归档 或克隆
Quarkus QuickstartsGit 存储库。sample 项目位于getting-started目录中。
对红帽文档提供反馈 复制链接链接已复制到粘贴板!
我们非常感谢您对我们的技术内容提供反馈,并鼓励您告诉我们您的想法。如果您想添加评论,提供见解、纠正拼写错误甚至询问问题,您可以在文档中直接这样做。
您必须有一个红帽帐户并登录到客户门户网站。
要从客户门户网站提交文档反馈,请执行以下操作:
- 选择 Multi-page HTML 格式。
- 点文档右上角的 反馈 按钮。
- 突出显示您要提供反馈的文本部分。
- 点高亮文本旁的添加反馈对话框。
- 在页面右侧的文本框中输入您的反馈,然后单击 Submit。
每次提交反馈时,我们都会自动创建跟踪问题。打开在点 Submit 后显示的链接,并开始监视问题或添加更多注释。
感谢您的宝贵反馈。
使开源包含更多 复制链接链接已复制到粘贴板!
红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。我们从这四个术语开始:master、slave、黑名单和白名单。由于此项工作十分艰巨,这些更改将在即将推出的几个发行版本中逐步实施。有关更多详情,请参阅我们的首席技术官 Chris Wright 提供的消息。
第 1 章 生成原生可执行文件 复制链接链接已复制到粘贴板!
您可以使用 Podman 或 Docker 等容器运行时从 Quarkus 应用程序生成原生可执行文件。Quarkus 使用构建器镜像生成二进制可执行文件,您可将其与 Red Hat Universal Base Images RHEL8-UBI 和 RHEL8-UBI 一同使用。红帽构建的 Quarkus 1.11 使用 registry.access.redhat.com/quarkus/mandrel-20-rhel8:20.3 作为 quarkus.builder-image 属性的默认值。
应用程序的原生可执行文件包含应用程序代码、所需库、Java API 以及虚拟机(VM)的更精简版本。较小的虚拟机基础提高了应用程序的启动时间,并生成最小磁盘占用量。
流程
打开 Getting Started 项目
pom.xml文件,并验证它是否包含原生配置集:<profiles> <profile> <id>native</id> <properties> <quarkus.package.type>native</quarkus.package.type> </properties> </profile> </profiles>注意使用 Quarkus
原生配置集可让您运行原生的可执行文件和原生镜像测试。使用以下方法之一构建原生可执行文件:
使用 Docker 构建原生可执行文件:
./mvnw package -Pnative -Dquarkus.native.container-build=true使用 Podman 构建原生可执行文件:
./mvnw package -Pnative -Dquarkus.native.container-build=true -Dquarkus.native.container-runtime=podman这些命令
在目标目录中创建getting-started-*-runner二进制文件。重要将 Quarkus 应用程序编译到原生可执行文件的过程中会占用大量内存。您可以通过设置
quarkus.native-image-xmx配置属性来限制原生编译过程中使用的内存量。设置低内存限制可能会增加构建时间。如需了解更多详细信息,请参阅 原生可执行文件配置属性。
运行原生可执行文件:
./target/getting-started-*-runner当您构建原生的可执行程序时,启用了
prod配置集,并使用prod配置集运行 Quarkus 原生测试。您可以使用quarkus.test.native-image-profile属性更改它。
第 2 章 创建自定义容器镜像 复制链接链接已复制到粘贴板!
您可以使用以下方法之一从 Quarkus 应用程序创建容器镜像:
- 手动创建容器
- 使用 OpenShift Docker 构建创建容器
将 Quarkus 应用程序编译到原生可执行文件的过程中会占用大量内存。您可以通过设置 quarkus.native-image-xmx 配置属性来限制原生编译过程中使用的内存量。设置低内存限制可能会增加构建时间。
2.1. 手动创建容器 复制链接链接已复制到粘贴板!
本节演示了如何使用您的应用程序为 Linux X86_64 手动创建容器镜像。当使用 Quarkus 原生容器生成原生镜像时,它会创建一个以 Linux X86_64 操作系统为目标的可执行文件。如果您的主机操作系统与这个操作系统不同,您将无法直接运行该二进制文件,您需要手动创建容器。
您的 Quarkus Getting Started 项目在 src/main/docker 目录中包含 Dockerfile.native,包含以下内容:
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3
WORKDIR /work/
RUN chown 1001 /work \
&& chmod "g+rwX" /work \
&& chown 1001:root /work
COPY --chown=1001:root target/*-runner /work/application
EXPOSE 8080
USER 1001
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
流程
使用以下方法之一构建原生 Linux 可执行文件:
使用 Docker 构建原生可执行文件:
./mvnw package -Pnative -Dquarkus.native.container-build=true使用 Podman 构建原生可执行文件:
./mvnw package -Pnative -Dquarkus.native.container-build=true -Dquarkus.native.container-runtime=podman
使用以下方法之一构建容器镜像:
使用 Docker 构建容器镜像:
docker build -f src/main/docker/Dockerfile.native -t quarkus-quickstart/getting-started .使用 Podman 构建容器镜像
podman build -f src/main/docker/Dockerfile.native -t quarkus-quickstart/getting-started .
运行容器:
使用 Docker 运行容器:
docker run -i --rm -p 8080:8080 quarkus-quickstart/getting-started使用 Podman 运行容器:
podman run -i --rm -p 8080:8080 quarkus-quickstart/getting-started
2.2. 使用 OpenShift Docker 构建创建容器 复制链接链接已复制到粘贴板!
您可以使用 OpenShift Docker 构建策略为 Quarkus 应用程序创建容器镜像。此策略使用集群中的构建配置创建容器。
先决条件
- 您可以访问 Red Hat OpenShift Container Platform 集群,并安装了 OpenShift CLI(oc)的最新版本。有关安装 oc 的详情,请参阅 安装和配置 OpenShift Container Platform 集群指南中的"安装 CLI"部分。
- OpenShift API 端点的 URL。
流程
登录到 OpenShift CLI:
oc login -u <username_url>在 OpenShift 中创建一个新项目:
oc new-project <project_name>基于
src/main/docker/Dockerfile.native文件创建构建配置:cat src/main/docker/Dockerfile.native | oc new-build --name <build_name> --strategy=docker --dockerfile -删除项目:
oc start-build <build_name> --from-dir .将项目部署到 OpenShift:
oc new-app <build_name>公开服务:
oc expose svc/<build_name>
第 3 章 原生可执行配置属性 复制链接链接已复制到粘贴板!
配置属性定义如何生成原生可执行文件。您可以使用 application.properties 文件配置 Quarkus 应用程序。
配置属性
下表列出了您可以设置的配置属性,以定义如何生成原生可执行文件:
| 属性 | 描述 | 类型 | 默认 |
|---|---|---|---|
|
| 传递给构建过程的额外参数。 | 字符串列表 | |
|
| 启用 HTTP URL 处理程序。这可让您为 HTTP URL 执行 URL.openConnection()。 | 布尔值 |
|
|
| 启用 HTTPS URL 处理程序。这可让您为 HTTPS URL 执行 URL.openConnection()。 | 布尔值 |
|
|
| 向原生镜像添加所有安全服务。 | 布尔值 |
|
|
| 向原生镜像添加所有字符集。这会增加镜像大小。 | 布尔值 |
|
|
| 包含Graal 发行版的路径。 | 字符串 |
|
|
| 包含 JDK 的路径。 |
| |
|
| 用于生成原生镜像的最大堆大小 Java 堆。 | 字符串 | |
|
| 等待调试器附加到构建过程,然后再运行原生镜像构建。对于那些熟悉 GraalVM 内部的用户,这是一个高级选项。 | 布尔值 |
|
|
| 使用 docker 和 debug-build-process 构建时会发布 debug 端口。 | 布尔值 |
|
|
| 重启原生镜像服务器。 | 布尔值 |
|
|
| 启用隔离以提高内存管理。 | 布尔值 |
|
|
| 如果原生镜像失败,则创建基于 JVM 的回退镜像。 | 布尔值 |
|
|
| 使用原生镜像服务器。这可以加快编译速度,但可能导致更改丢失,因为缓存失效问题。 | 布尔值 |
|
|
| 自动注册所有 META-INF/services 条目。 | 布尔值 |
|
|
| 转储所有代理的字节码以进行检查。 | 布尔值 |
|
|
| 使用容器运行时进行构建。Docker 被默认使用。 | 布尔值 |
|
|
| 构建镜像的 docker 镜像。 | 字符串 |
|
|
| 用于构建镜像的容器运行时。例如,Docker: | 字符串 | |
|
| 传递给容器运行时的选项。 | 字符串列表 | |
|
| 在镜像中启用虚拟机内省。 | 布尔值 |
|
|
| 在镜像中启用完整的堆栈追踪。 | 布尔值 |
|
|
| 生成调用路径和包含的软件包/类/方法的报告。 | 布尔值 |
|
|
| 报告例外情况,包括完整的堆栈跟踪。 | 布尔值 |
|
|
| 运行时报告错误。如果您使用不支持的功能,这可能会导致应用程序在运行时失败。 | 布尔值 |
|
|
|
以逗号分隔的 glob 列表,以匹配应添加到原生镜像中的资源路径。在所有平台中使用斜杠( | 字符串列表 | |
|
|
启用 debug,并在单独的 .debug 文件中生成调试符号。当与 | 布尔值 |
|
支持的 glob 功能及其描述
下表列出了支持的 glob 功能及其描述:
| 字符 | 功能描述 |
|
|
匹配不包含斜杠( |
|
|
匹配可能包含斜杠( |
|
| 匹配一个字符,但不匹配斜杠。 |
|
| 匹配括号中指定的范围中的一个字符,但不匹配斜杠。 |
|
| 匹配括号中指定的范围中的一个字符,但不匹配斜杠。 |
|
| 匹配没有在括号中指定的一个字符; 不匹配斜杠。 |
|
| 匹配括号中指定的范围之外的一个字符; 不匹配斜杠。 |
|
| 匹配以逗号分隔的任何更改器令牌;令牌可以包含通配符、嵌套的修改和范围。 |
|
|
转义字符。转义有三种级别: |
3.1. 为 Quarkus 原生编译配置内存消耗 复制链接链接已复制到粘贴板!
将 Quarkus 应用程序编译到原生可执行文件的过程中会占用大量内存。您可以通过设置 quarkus.native-image-xmx 配置属性来限制原生编译过程中使用的内存量。设置低内存限制可能会增加构建时间。
流程
使用以下方法之一为
quarkus.native-image-xmx 属性设置值,以限制原生镜像构建期间的内存消耗:使用
application.properties文件:quarkus.native.native-image-xmx=<maximum_memory>设置系统属性:
mvn -Pnative -Dquarkus.native.container-build=true -Dquarkus.native.native-image-xmx=<maximum_memory>此命令通过 Docker 构建原生可执行文件。添加
-Dquarkus.native.container-runtime=podman参数以使用 Podman。
例如,要将内存限制设置为 6 GB,请输入 quarkus.native.native-image-xmx=6g。该值必须是大于 2MB 的倍数。附加字母 m 或 M 表示兆字节,或 g 或 G 表示千兆字节。
第 4 章 测试原生可执行文件 复制链接链接已复制到粘贴板!
测试以原生模式运行的应用程序,以测试原生可执行文件的功能。使用 @NativeImageTest 注释构建原生可执行文件,并根据 http 端点运行测试。
流程
打开
pom.xml文件,再验证原生配置集是否包含以下元素:<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <version>${surefire-plugin.version}</version> <executions> <execution> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> <configuration> <systemPropertyVariables> <native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path> <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager> <maven.home>${maven.home}</maven.home> </systemPropertyVariables> </configuration> </execution> </executions> </plugin>failsafe-maven-plugin运行集成测试,并指示生成的原生可执行文件的位置。打开
src/test/java/acme/quickstart/NativeGreetingResourceIT.java文件,并验证它是否包含以下内容:package org.acme.quickstart; import io.quarkus.test.junit.NativeImageTest; @NativeImageTest1 public class NativeGreetingResourceIT extends GreetingResourceTest {2 // Run the same tests }运行测试:
./mvnw verify -Pnative以下示例显示了这个命令的输出:
./mvnw verify -Pnative ... [getting-started-1.0-SNAPSHOT-runner:18820] universe: 587.26 ms [getting-started-1.0-SNAPSHOT-runner:18820] (parse): 2,247.59 ms [getting-started-1.0-SNAPSHOT-runner:18820] (inline): 1,985.70 ms [getting-started-1.0-SNAPSHOT-runner:18820] (compile): 14,922.77 ms [getting-started-1.0-SNAPSHOT-runner:18820] compile: 20,361.28 ms [getting-started-1.0-SNAPSHOT-runner:18820] image: 2,228.30 ms [getting-started-1.0-SNAPSHOT-runner:18820] write: 364.35 ms [getting-started-1.0-SNAPSHOT-runner:18820] [total]: 52,777.76 ms [INFO] [INFO] --- maven-failsafe-plugin:2.22.1:integration-test (default) @ getting-started --- [INFO] [INFO] ------------------------------------------------------- [INFO] T E S T S [INFO] ------------------------------------------------------- [INFO] Running org.acme.quickstart.NativeGreetingResourceIT Executing [/data/home/gsmet/git/quarkus-quickstarts/getting-started/target/getting-started-1.0-SNAPSHOT-runner, -Dquarkus.http.port=8081, -Dtest.url=http://localhost:8081, -Dquarkus.log.file.path=build/quarkus.log] 2019-04-15 11:33:20,348 INFO [io.quarkus] (main) Quarkus 999-SNAPSHOT started in 0.002s. Listening on: http://[::]:8081 2019-04-15 11:33:20,348 INFO [io.quarkus] (main) Installed features: [cdi, resteasy] [INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.387 s - in org.acme.quickstart.NativeGreetingResourceIT ...注意Quarkus 等待 60 秒,让原生镜像在自动进行原生测试前启动。您可以使用
quarkus.test.native-image-wait-time系统属性更改这个持续时间。您可以使用以下命令扩展等待时间,其中 <
duration> 是等待时间(以秒为单位):./mvnw verify -Pnative -Dquarkus.test.native-image-wait-time=<duration>
4.1. 当作为原生可执行文件运行时排除测试 复制链接链接已复制到粘贴板!
当您对原生应用程序运行测试时,您只能与其 HTTP 端点交互。测试不会原生运行,因此它们无法链接到您在 JVM 上运行时应用程序代码。
您可以在 JVM 和原生执行间共享测试类,并使用 @DisabledOnNativeImage 注释来排除某些测试,使其仅在 JVM 上运行。
4.2. 测试现有原生可执行文件 复制链接链接已复制到粘贴板!
您可以针对现有的可执行构建进行测试。这样,您可以在构建后的二进制阶段运行多个测试集合。
流程
针对已经构建的原生可执行文件运行测试:
./mvnw test-compile failsafe:integration-test此命令使用 Failsafe Maven 插件针对现有原生镜像运行测试。
另外,您可以使用以下命令指定到原生可执行文件的路径,其中 <
path>是原生镜像路径:./mvnw test-compile failsafe:integration-test -Dnative.image.path=<path>
第 5 章 其他资源 复制链接链接已复制到粘贴板!
修订于 2023-01-28 19:57:02 +1000