领先一步
VMware 提供培训和认证,助您加速进步。
了解更多Spring Boot开发者如何以最小的限制提高其应用程序的运行时效率,从而在大多数应用程序中享受这些好处?答案是Spring Boot 3.3引入的CDS支持,它允许您更快地启动Spring Boot应用程序并消耗更少的内存。它基于我几个月前介绍的Spring Framework 6.1引入的基础。
一个关键点是,这种新的 CDS 支持提供了与 GraalVM 原生镜像支持 不同的价值主张:CDS 带来的改进在启动时间等方面不如原生镜像那么显著,但仍然非常重要,同时您可以继续使用常规 JVM,并且副作用极小。
Spring Boot 以生产就绪的方式同时支持 CDS 和 GraalVM 原生镜像,并根据您的上下文和偏好提供选择。
CDS 代表 类数据共享(Class Data Sharing),它是一种成熟的技术,已在大多数 JVM 中可用和使用,但迄今尚未充分发挥其潜力。简单来说,您可能已经在不知不觉中使用了 CDS,但仅用于优化 JDK 类的加载,而您的应用程序或库的类可能没有利用它。要解锁这一点,需要对您的应用程序进行训练运行。
您还需要满足一组约束,如果没有像 Spring Boot 这样的专用支持,这些约束很容易被打破
* 通配符和嵌套 JAR。Spring Boot 3.3 通过提供 2 个新功能解锁了这一潜力:自解压可执行 JAR 和 Buildpacks CDS 支持。
直接使用可执行 JAR 运行 java -jar my-app.jar 并不是在生产环境中运行应用程序最有效的方式。这在文档中有所说明,但根据我与 Spring 社区进行的各种讨论,大多数不使用 Buildpacks 的开发人员和运维人员都错过了这一点。直到最近,还没有真正的一等功能来提供帮助。
Spring Boot 3.3 改变了这一点,引入了可执行 JAR 自解压的能力,无需任何外部工具,只需使用可能已用于运行应用程序的 java 命令即可
java -Djarmode=tools -jar my-app.jar extract --destination application

然后您可以使用以下方式更高效地运行您的 Spring Boot 应用程序
java -jar application/my-app.jar
此功能具有一项超能力:它旨在满足 CDS(和 Project Leyden)约束。因此,结合 Spring Framework 对 CDS 训练运行的支持,您可以为您的 Spring Boot 应用程序创建 CDS 存档,如下所示
java -XX:ArchiveClassesAtExit=application.jsa -Dspring.context.exit=onRefresh -jar application/my-app.jar
然后您可以通过以下方式启动启用 CDS 的应用程序
java -XX:SharedArchiveFile=application.jsa -jar application/my-app.jar
自解压可执行 JAR 功能与 CDS 用法相结合是灵活的,但仍然需要相当多的手动步骤,因此 Spring Boot 和 Buildpacks 为 CDS 提供了集成支持,它

如 https://github.com/sdeleuze/spring-boot-cds-demo 仓库中所示,可以通过 Gradle 启用如下
tasks.named("bootBuildImage") {
environment["BP_JVM_CDS_ENABLED"] = "true"
}
或者使用 Maven
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<env>
<BP_JVM_CDS_ENABLED>true</BP_JVM_CDS_ENABLED>
</env>
</image>
</configuration>
</plugin>
在训练运行期间,Spring bean 会被实例化而无需启动 Spring 生命周期,因此实际上您可能观察到的主要副作用是早期数据库交互,这可以通过配置您的应用程序(或仅通过 CDS_TRAINING_JAVA_TOOL_OPTIONS 环境变量配置训练运行)来避免,以防止此类数据库交互,具体如此处文档所述。
也可以使用 BP_SPRING_AOT_ENABLED 环境变量触发 Spring AOT 激活支持,但请务必牢记这些限制
CDS_TRAINING_JAVA_TOOL_OPTIONS 和 BP_SPRING_AOT_ENABLED 不能组合使用。Broadcom 的 Spring 和 Buildpacks 团队一直在密切合作,利用这些 OSS 功能并将其与额外的 Tanzu Platform 功能结合起来,为 Cloud Foundry 或 Kubernetes 提供一流的 CDS 支持,例如允许训练运行自动配置,使 CDS 像一个标志一样易于启用而没有副作用,并且更多平台级别的功能即将推出。
在 MacBook M2 上运行的最小 Spring MVC Tomcat 应用程序中,我们观察到,与运行可执行 JAR 相比,提取的应用程序与 CDS 结合使用可实现大约 1.5 倍的启动速度和 16% 的内存消耗降低。如果我们将 Spring AOT 加入,我们将获得大约 2 倍的启动速度和 27% 的内存消耗降低。

我们在 Petclinic 上也看到了类似的改进。

在性能较弱的云实例上,这些值显然会发生变化,但您应该会观察到类似的改进比率。
有趣的是,上述新提取命令使用的对 CDS 友好的布局也旨在为 Project Leyden Early-Access 版本提供最佳性能,这可以看作是 CDS 的继任者,具有额外的功能,可实现
我们目前观察到,使用 Project Leyden 的 Spring Boot 应用程序启动速度大约快 3 倍,结合 Project Leyden 和 Spring AOT 后启动速度快 4 倍。

我将在即将举行的 Devoxx Belgium 2024 的 Project Leyden 演讲中分享更多内容,届时我将与 Java 平台团队的 Per Minborg 共同展示。