“
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
以下是与从自动检查点恢复相关的启动时间结果:
太酷了,启动时间比原来快一个数量级,而且无需更改代码。
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
这个手动触发的检查点不仅包含框架代码,还包含应用程序代码,这意味着我们应该会看到启动速度更快,因为应用程序已由框架加载和启动。以下是结果:
四、特别说明
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 条评论