CDS(Class Data Sharing)在 Spring 6.1 中的应用
正如 官方文档 所述,类数据共享(CDS)通过将类元数据缓存在 Archive(归档/存档) 文件中,使其可以快速预加载到新启动的 JVM 中,从而帮助缩短 JVM 的启动时间和内存占用。这加快了类加载速度,而类加载速度是启动时间的一个重要因素。大多数最新的 JDK 发行版中预先打包了默认的 CDS 归档,其中包含了常见 JDK 类的元数据。你也可以创建自定义的 CDS 归档,以加快类在自己应用中的加载速度。
GraalVM 原生镜像 和 Project CRaC 都能让 Spring Boot 应用在几十毫秒内启动。那么,为什么要关注 CDS 呢?
主要有三个原因:
- 它是 OpenJDK 主线中成熟且可用于生产的技术,与 GraalVM 和 Project CRaC 相比,它更易于使用,因为它具有较少的限制和副作用。
- 正如 Brian Goetz 在他在 Devoxx 上的 Project Leyden 演讲 中提到的:“大多数人今天不使用 CDS,但可能应该使用,因为他们可以通过相对较少的工作获得合理的启动性能提升。”
- 在每一个新的 JVM 版本中,这项技术都会变得越来越好,Project Leyden 的目标是在不久的将来增加更多的优势。
接下来,让我们一起探究 CDS 能为你的 Spring 应用带来什么?
在 Spring 6.1 中引入 CDS 初始支持
Spring 6.1 带来了一个新的 “类数据共享” 文档章节,解释了优化应用的两个步骤:
- 使用新增的
-Dspring.context.exit=onRefresh
JVM 系统属性,可以通过训练运行创建 CDS 归档,在大多数使用情况下,无需启动 Bean 或访问远程服务。 - 使用归档来优化生产环境的启动。
要使 CDS 优化发挥最大效果,必须确保创建归档和启动应用时所使用的 JDK 和类路径完全相同。
还要注意的是,要有效地缓存类:
- classpath 应指定为一个常规的非嵌套 JAR 列表。
- 避免使用目录。
- 避免
*
通配符扩展。
由于 Spring Boot 可执行 JAR 或 非打包部署 目前还不能满足所有这些条件,因此它们还不能实现最佳的 CDS 性能。
因此,我们与 Stéphane Nicoll 合作,开发了一个 CDS 友好的非打包部署方案,以便能够获取相关的数据点,并为 Spring 开发人员提供探索 CDS 支持的途径,而不对 Spring Boot 在更集成的方式下提供 CDS 支持 做出任何假设。请参阅相关的 spring-boot#38276 issue 以获取更多详细信息。
如果你想在自己的应用中使用 CDS 并提供反馈,可以尝试从 spring-cds-demo 仓库中获得灵感,该仓库包含一个自带的 unpack-executable-jar.sh
脚本,它能以最佳方式解压缩 Spring Boot 可执行 JAR,从而实现 CDS 的最佳性能。你还可以试试 Stéphane 制作的 cds-log-parser 工具,它能生成报告,显示哪些类是从 CDS 缓存中加载的。
Spring Petclinic 和 CDS
来看看从著名的 Spring Petclinic 应用的数据点中能学到什么,该应用部署了 CDS 优化,运行在 Java 21 上,并可选择与 Spring AOT 优化相结合。
第一个要点与 CDS 无关,但已经被广泛认知和记录,但值得强调:为了实现最佳的启动时间,Spring Boot 应用的生产部署应该是 非打包部署。如果你正在使用 Buildpacks,则已经符合此要求。如果没有,你可能需要检查并可能改进你的自定义部署方式。
与非打包部署相比,CDS 优化可以将启动时间减少 30 %至 35%,只需创建几十 Mb 大小的 CDS 归档并将其与应用一起使用。当然,与 GraalVM 或 Project CRaC 相比,这种收益并不那么显著,但你也不需要做很多工作就能获得这些好处。因此,如果集成得当,CDS 可能具有被广泛采用的巨大潜力。如果将 CDS 与 Spring AOT 优化相结合,可以将 Petclinic 的启动时间减少 36% 至 42%。
总结
像往常一样,我们期待 Spring 社区的反馈,以帮助我们思考下一步可能采取的措施,从而实现更加集成的体验。例如,你是否对通过 CDS 缓存自动构建 Spring Boot 优化容器的功能感兴趣?
展望未来,Spring 团队将继续与 Java Platform 团队合作,研究如何利用这些改进和发现与 Project Leyden premain 优化 相结合,在 JVM 上提高运行时效率,同时尽可能减少对 Spring 开发人员和操作人员的限制。
Ref:https://spring.io/blog/2023/12/04/cds-with-spring-framework-6-1