JVM Checkpoint Restore

Spring Framework 与 Project CRaC实现的检查点/恢复集成,以便允许实现能够通过 JVM 减少基于 Spring 的 Java 应用程序的启动和预热时间的系统。 使用此功能需要:

  • 启用检查点/还原的 JVM(目前仅限 Linux)。

  • 类路径中存在 org.crac:crac 库(支持版本 1.4.0 和更高版本)。

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

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

从概念上讲,检查点和恢复与 Spring Lifecycle contract 保持一致,适用于单独的 bean。

On-demand checkpoint/restore of a running application

可以按需创建检查点,例如使用 jcmd application.jar JDK.checkpoint 之类的命令。在创建检查点之前,Spring 停止所有正在运行的 bean,让它们有机会通过实现 Lifecycle.stop 关闭资源(如果需要)。恢复后,重新启动相同的 bean,Lifecycle.start 允许 bean 在相关时重新打开资源。对于不依赖于 Spring 的库,可以通过实现 org.crac.Resource 并注册相关实例,提供自定义的检查点/恢复集成。

利用正在运行应用程序的检查点/恢复通常需要额外的生命周期管理才能正常停止并开始使用文件或套接字等资源,并停止活动线程。

如果在热身 JVM 上创建检查点,则恢复的 JVM 也将获得同样的热身,从而立即允许潜在的峰值性能。这种方法通常需要访问远程服务,因此需要某种程度的平台集成。

Automatic checkpoint/restore at startup

当设置 -Dspring.context.checkpoint=onRefresh JVM 系统属性时,将在 LifecycleProcessor.onRefresh 阶段自动创建检查点。此阶段完成后,所有非延迟初始化的单例均已实例化,并且已经调用了 InitializingBean#afterPropertiesSet 回调;但生命周期尚未开始,并且尚未发布 ContextRefreshedEvent

出于测试目的,还可以利用 -Dspring.context.exit=onRefresh JVM 系统属性,该属性会触发类似的行为,但不是创建检查点,而是在相同的生命周期阶段退出 Spring 应用程序,而无需 Project CraC 依赖项/JVM 或 Linux。当 bean 未启动并且可能会优化配置以避免这种情况时,这有助于检查是否需要连接到远程服务。

如上所述,特别是在 CRaC 文件作为可部署工件(例如容器映像)的一部分运送的用例中,在假设任何 JVM “看到”的敏感数据最终都会出现在 CRaC 文件中时进行操作,并仔细评估相关的安全影响。

自动检查点/恢复是一种方式,可以“快进”应用程序的启动到应用程序上下文即将开始的阶段,但它不允许完全热身 JVM。