AppCDS
本参考指南解释了如何在 Quarkus 应用程序中启用应用程序类数据共享。
什么是应用程序类数据共享 (AppCDS)?
应用程序类数据共享是一项 JVM 功能,有助于减少 JVM 应用程序的启动时间和内存占用。这是通过让 JVM 创建一个预处理的共享类存档来实现的,这些类在启动时被加载。由于每次应用程序启动时都会加载这些类,因此 AppCDS 是一种改进应用程序启动时间的简单方法,而无需应用程序本身以特定方式进行编码或配置。改进的程度取决于许多因素,例如加载的类数量、底层硬件等。
标准 AppCDS 生成
手动为应用程序创建 AppCDS 的主要缺点是,其生成过程要求使用特殊标志启动应用程序,并在应用程序部署到生产环境之前的一步中获取存档。
具体过程取决于所使用的 JVM 版本,因为较新版本的 JVM 逐步简化了该过程。 |
这一事实使得 AppCDS 难以用于实际部署,在这些部署中,CI 管道负责构建和部署应用程序。
Quarkus 中的 AppCDS
创建存档
Quarkus 使 AppCDS 生成变得像将 quarkus.package.jar.appcds.enabled
配置属性设置为 true
一样简单。对于使用 Maven 的示例 Quarkus 应用程序(假定它位于 /tmp/code-with-quarkus
),可以通过像这样构建应用程序来简单地生成 AppCDS 存档:
./mvnw package -Dquarkus.package.jar.appcds.enabled=true
构建完成后,输出将包含(除其他外)以下内容:
[INFO] [io.quarkus.deployment.pkg.steps.AppCDSBuildStep] Launching AppCDS creation process.
[INFO] [io.quarkus.deployment.pkg.steps.AppCDSBuildStep] AppCDS successfully created at: '/tmp/code-with-quarkus/target/quarkus-app/app-cds.jsa'.
[INFO] [io.quarkus.deployment.pkg.steps.AppCDSBuildStep] To ensure they are loaded properly, run the application jar from its directory and also add the '-XX:SharedArchiveFile=app-cds.jsa' JVM flag.
Moreover, make sure to use the exact same Java version (x.y.z) to run the application as was used to build it.
如果我们查看 /tmp/code-with-quarkus/target/quarkus-app
,除了其他文件外,我们还会看到 app-cds.jsa
,这就是生成的 AppCDS 存档。
使用存档
使用存档是通过使用 -XX:SharedArchiveFile
标志来完成的。但是,有一些注意事项:
-
Quarkus jar 文件和 AppCDS 存档的路径必须与 Quarkus 用于构建存档的路径完全相同。
-
运行应用程序的 JVM 版本必须**完全**与构建 Quarkus 应用程序时使用的版本相同。
假设我们使用与构建应用程序相同的 JVM 来运行应用程序,我们可以这样启动应用程序:
cd target/quarkus-app
java -XX:SharedArchiveFile=app-cds.jsa -jar quarkus-run.jar
JVM 是有弹性的。当存档文件无法使用时(无论出于何种原因),它将简单地禁用 AppCDS 功能。 如果希望在存档文件无法使用时停止执行,可以使用以下命令行调用:
|
鉴于上述关于如何启动应用程序以构建存档的说明,一个问题随之而来:Quarkus 如何处理这种情况? 答案是,在应用程序构建时,在应用程序存档构建完成后,Quarkus 会启动应用程序,但只运行启动过程中安全的那些部分。更具体地说,应用程序的运行会进行到实际打开套接字或运行应用程序逻辑的步骤。 因此,存档生成过程一方面是完全安全的,但另一方面无法存档应用程序在启动时可能需要的每一个类。因此,用户可以预期通过手动完成生成 AppCDS 存档的繁琐步骤来获得稍微更有效的存档。 |
AppCDS 在最新的 JDK 版本中有了显著的改进。这意味着为了确保它带来最佳的改进,请确保您的项目目标是尽可能高的 Java 版本(最好是 17 或 21)。 |
从 JDK 24 开始,JVM 提供了一种类数据共享的演进形式,即 AOT 缓存。如果您正在构建一个将面向 JDK 24+ 的应用程序,您可以通过在打包应用程序时添加以下系统属性来利用此功能:
此标志(加上原始的 您可以在启动应用程序时像这样使用此 AOT 缓存:
|
在容器中使用
使用 quarkus-container-image-jib
扩展构建容器镜像时,Quarkus 会自动处理生成存档并使其在容器中运行时可用的所有必要步骤。
这样,只需将 quarkus.package.jar.appcds.enabled
设置为 true
,使用生成镜像的容器就可以受益于启动时间和内存使用量的轻微减少。
您可能会注意到 Quarkus 启动了一个容器来生成 AppCDS 存档。它这样做是为了确保构建的 Java 版本与生成的容器镜像的 Java 版本保持一致。可以通过将 quarkus.package.jar.appcds.use-container
设置为 false
来选择退出此功能。在这种情况下,您有责任确保运行 Quarkus 应用程序的 Java 版本与构建机器上的 Java 版本匹配。