PIG 微服务已支持 SpringBoot3.2 、SpringCloud 2023

源码下载:https://gitee.com/log4j/pig.git -b 2023

一、前言

Spring 6.1 和 Spring Boot 3.2 已发布,在这两个版本中它们均全面支持 CRaC(Coordinated Restore at Checkpoint)。

CRaC 是 OpenJDK 项目,能够把运行中的 JVM,将其状态(包括您的应用程序)存储到磁盘中。然后,在另一个时间点,您可以从保存的检查点将 JVM 恢复到内存中。通过这种方式,可以启动一个应用程序,预热它,并创建一个检查点。从保存的检查点恢复到内存主要依赖于磁盘 I/O,这意味着速度非常快(在毫秒级别)。

为了测试 Spring Boot 3.2 对 CRaC 的支持,我将使用 Spring Boot Petclinic进行演示。

二、依赖

要在 Spring Boot 3.2 中使用 CRaC,您需要满足以下三个条件:

  • 支持 CRaC 的 JVM
  • org.crac 的 jar 依赖
  • 可以存储检查点的文件夹

2.1 安装 Zulu JDK

首先需要使用的 JDK 是Azul Zulu 21.0.1 + CRaC,下载地址:https://www.azul.com/downloads/?os=linux&package=jdk-crac。
Azul 提供了 x64、aarch64 CPU 架构和 JDK 17 和 JDK 21 支持 CRaC 的 JDK 版本。CRaC 目前仅在 Linux 上可用,MacOS 和 Windows 还需要等待。

为了能够使用 CRIU,可能需要设置权限。在 Linux 机器上执行以下命令:

sudo chown root:root $JAVA_HOME/lib/criu
sudo chmod u+s $JAVA_HOME/lib/criu

2.2 添加 jar 依赖

首先克隆 Petclinic 代码,并添加 org.crac 依赖。我们可以在 Maven 中央库中找到 org.crac,可以按以下方式添加依赖项:

dependency>
  groupId>org.cracgroupId>
  artifactId>cracartifactId>
  version>1.4.0version>
dependency>

三、基线测试

我在 JDK(17 和 21)上进行测试,首先仅仅从 17 切换到 21 就已经将 Petclinic 的启动时间减少了 500 毫秒!

因此,如果可能的话,您应该尽快升级到 JDK 21 以获取更好的性能。通过执行以下命令来启动应用程序:

java -jar spring-petclinic-3.2.0.jar

以下是启动的耗时统计:

虽然启动时间快了大约 500 毫秒,但整体上还是需要 4 秒钟整体启动。因此让我们看一下在 Spring Boot 3.2 中实现的另一个新方法。

3.1 使用 CRaC 自动检查点

通过在应用程序启动之前自动创建一个检查点来改善 Spring Boot 应用的启动时间。

当设置了-Dspring.context.checkpoint=onRefresh JVM 系统属性时,在启动过程中的 LifecycleProcessor.onRefresh 阶段会自动创建一个检查点。在此阶段完成后,所有非懒加载的单例都已被实例化,并调用了InitializingBean#afterPropertiesSet回调;这个时候应用程序生命周期尚未开始,并且ContextRefreshedEvent尚未发布。

  • 要使用自动检查点功能,我们需要按以下方式启动应用程序:
java -Dspring.context.checkpoint=onRefresh -XX:CRaCCheckpointTo=./tmp_checkpoint -jar spring-petclinic-3.2.0.jar

执行应用程序后,它会创建检查点,将检查点文件存储在./tmp_checkpoint 文件夹中,然后退出应用程序。

  • 现在,您可以通过执行以下命令从检查点中恢复应用程序(也就是重新启动):
java -XX:CRaCRestoreFrom=./tmp_checkpoint

以下是与从自动检查点恢复相关的启动时间结果:

image1.png

太酷了,启动时间比原来快一个数量级,而且无需更改代码。

3.2 手动开启检查点

使用手动检查点可以比自动检查点更快地启动应用程序。

在使用手动检查点时,您可以在任何时间创建检查点。比如您可能希望在 10 分钟后或应用程序完全预热(大部分/全部代码已编译和优化)后创建检查点。

创建手动检查点的过程与自动检查点类似,唯一的区别是您通过外部触发检查点,而不是由框架自动创建检查点。

在开始之前,请确保检查点文件夹为空。

  • 首先,按以下方式启动应用程序:
java -XX:CRaCCheckpointTo=./tmp_checkpoint -jar spring-petclinic-3.2.0.jar
  • 等待应用程序完全启动,在第二个 Shell 窗口中,执行以下命令:
jcmd spring-petclinic-3.2.0.jar JDK.checkpoint

现在,您应该看到在您启动 petclinic 应用程序的第一个 Shell 窗口中创建了一个检查点,并且应用程序已关闭。

通过验证文件夹./tmp_checkpoint中是否包含检查点文件,您可以检查应用程序是否已进行了检查点。

现在,您可以关闭第二个 Shell 窗口。

要从此检查点恢复应用程序,您执行与自动检查点相同的命令:

java -XX:CRaCRestoreFrom=./tmp_checkpoint

这个手动触发的检查点不仅包含框架代码,还包含应用程序代码,这意味着我们应该会看到启动速度更快,因为应用程序已由框架加载和启动。以下是结果:

image2.png

四、特别说明

Spring Boot 3.2 已经完全支持 CRaC,无需对代码进行修改。意味着只要使用 Spring Boot,框架将在检查点之前负责关闭资源,并在应用恢复之后重新打开它们。

如果您使用其他框架,则需要在相关类中实现 CRaC Resource 接口,并在beforeCheckpoint()方法中关闭这些资源(例如打开的文件或 socket 连接),并在afterRestore()方法中重新打开这些资源。

五、结论

正如我们所看到的,使用 CRaC 可以显著减少 Spring Boot 3.2 应用程序的启动时间。

如果不想修改代码,我们可以通过简单地在 Spring Boot 3.2 中使用自动检查点功能,将启动时间缩短一个数量级。当然,追求更快的启动速度,我们可以手动创建一个检查点。

对比 GraalVM Native Image,CRaC 的优势在于它可以在通用的 JVM 上运行,并且代码可以在检查点恢复之后得到进一步优化。

原文链接:https://foojay.io/today/springboot-3-2-crac ,春哥、冷冷翻译并添加了部分图方便理解 CRaC 的原理。

PIG 微服务已支持 SpringBoot3.2 、SpringCloud 2023
源码下载:https://gitee.com/log4j/pig.git -b 2023


0 条评论

发表回复

Avatar placeholder

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

蜀ICP备16001794号
© 2014 - 2024 linpxing.cn All right reserved.