跳到主要内容
版本:7.0.3

JVM 检点恢复

Hunyuan 7b 中英对照 JVM Checkpoint Restore

Spring框架与Project CRaC实现的检查点/恢复功能进行了集成,从而能够构建出能够缩短基于Spring的Java应用程序(运行在JVM上)的启动和预热时间的系统。

使用此功能需要:

  • 启用检查点/恢复功能的JVM(目前仅支持Linux)。

  • 类路径中包含org.crac:crac库(支持1.4.0及以上版本)。

  • 指定所需的java命令行参数,例如-XX:CRaCCheckpointTo=PATH-XX:CRaCRestoreFrom=PATH

注意

当请求检查点时,由 -XX:CRaCCheckpointTo=PATH 指定的路径中生成的文件包含了正在运行的 JVM 的内存表示,这些文件可能包含机密信息和其他敏感数据。使用此功能时应假定 JVM “看到”的任何值(例如来自环境的配置属性)都会被存储在这些 CRaC 文件中。因此,应仔细评估这些文件的生成、存储和访问位置及方式所带来的安全影响。

从概念上讲,检查点(checkpoint)和恢复(restore)功能与Spring生命周期契约中对单个Bean的规范是一致的。

按需检查点/恢复正在运行的应用程序

可以根据需要创建检查点,例如使用如下命令:jcmd application.jar JDK.checkpoint。在创建检查点之前,Spring 会停止所有正在运行的 Bean,以便它们可以通过实现 Lifecycle.stop 方法来关闭资源(如有必要)。恢复后,这些 Bean 会重新启动,此时 Lifecycle.start 方法会允许 Bean 在适当的时候重新打开资源。对于不依赖于 Spring 的库,可以通过实现 org.crac.Resource 并注册相关实例来提供自定义的检查点/恢复集成。

注意

利用运行中应用程序的检查点/恢复功能通常需要额外的生命周期管理,以便优雅地停止和启动对文件或套接字等资源的使用,并终止活跃的线程。

注意

请注意,当以固定频率定义调度任务时(例如使用@Scheduled(fixedRate = 5000)这样的注解),在检查点与恢复之间错过执行的所有任务都将在JVM通过按需检查点/恢复功能恢复时被执行。如果这不是您希望的行为,建议您以固定延迟来调度任务(例如使用@Scheduled(fixedDelay = 5000)),或者使用Cron表达式进行调度,因为这些延迟值会在每次任务执行后重新计算。

备注

如果在已经预热好的JVM上创建检查点,那么恢复后的JVM也会处于同样预热状态,从而可以立即发挥出峰值性能。这种方法通常需要访问远程服务,因此需要一定程度的平台集成。

启动时自动检查点/恢复

当设置了JVM系统属性 -Dspring.context.checkpoint=onRefresh 时,在启动过程中会自动在 LifecycleProcessor.onRefresh 阶段创建一个检查点(checkpoint)。在此阶段完成后,所有非延迟初始化的单例(singletons)都会被实例化,并且 InitializingBean#afterPropertiesSet 回调方法也会被调用;但是单例的生命周期(lifecycle)尚未开始,ContextRefreshedEvent 也尚未被发布(即尚未触发)。

出于测试目的,还可以利用 -Dspring.context.exit=onRefresh 这一 JVM 系统属性来触发类似的行为,但这种方式不会创建检查点(checkpoint),而是在应用程序的同一生命周期阶段直接退出 Spring 应用程序,且无需依赖于 Project CraC、JVM 或 Linux 环境。当某些 Bean 尚未启动时,这种方法有助于检查是否需要与远程服务建立连接,并可以据此优化配置以避免此类问题。

注意

如上所述,特别是在CRaC文件作为可部署工件(例如容器镜像)的一部分进行交付的情况下,在使用过程中应假设JVM“看到”的任何敏感数据最终都会被包含在CRaC文件中,并仔细评估相关的安全影响。

备注

自动检查点/恢复是一种“快进”应用程序启动过程的方法,可以使其快速进入应用程序上下文即将启动的阶段,但它无法确保JVM已经完全预热。