Spring Boot 服务的 RAM 消耗减少多达 30% ,为研究Spring Boot而量身定制的 Alpaquita 容器。Buidpacks也可用!
重要提示:Project Leyden EA 版本基于实验代码,不适用于生产用途。此外,EA 版本中的某些功能可能会更改或删除,工作流程也可能会更改。
1.Leyden是什么?
Project Leyden 是一个 OpenJDK 项目,自 2022 年以来一直在筹备中。该项目旨在利用 CDS(类数据共享)和提前优化来选择性地将计算从运行时转移和约束到某个时间点 — 例如到更早的阶段。
最终目标是在封闭世界约束下创建完全静态的镜像。封闭世界约束可以实现更强大的启动优化,正如我们在 GraalVM Native Image 中看到的那样。但它与 Java 的动态性不太相符。因此,目前,Leyden 项目团队正在探索可以适用于更广泛应用程序的较弱约束。
Project Leyden 在开发阶段可以做什么?它在试运行期间观察应用程序行为,并根据观察结果执行某些计算。试运行后,它会创建一个 CDS 存档,其中包含类元数据、方法分析器和编译后的代码(例如试运行期间经常使用的方法)。因此,当您执行应用程序的生产运行时,它会使用 CDS 存档中的数据并启动得更快。
2.在SpringBoot中使用Leyden
2.1.实验准备
- Spring Petclinic for Spring Boot 3.3
- M1 MacBook Air
2.2.编译
mvn -Dmaven.test.skip=true clean package
2.3.打包
java -Djarmode=tools -jar target/spring-petclinic-3.3.0-SNAPSHOT.jar extract
当您使用 -Djarmode=tools 实用程序时,Spring 会使用各种布局将应用程序提取到目录中。在默认布局的情况下,该目录将包含:
- 包含库的 lib 子目录
- 包含应用程序类和引用 lib 文件夹中的库的清单的应用程序 JAR
3.试运行
java -XX:CacheDataStore=SpringPetclinic.cds -jar spring-petclinic-3.3.0-SNAPSHOT/spring-petclinic-3.3.0-SNAPSHOT.jar
将创建两个文件:
- SpringPetclinic.cds 包含类元数据、堆对象和分析数据;
- SpringPetclinic.cds.code 包含 AOT 编译方法(计划将来将此文件与 SpringPetclinic.cds 合并)
3.生产运行
java -XX:CacheDataStore=SpringPetclinic.cds -jar spring-petclinic-3.3.0-SNAPSHOT/spring-petclinic-3.3.0-SNAPSHOT.jar
通过生产模式运行,启动速度将会加快3倍左右。
4.使用Leyden前后的类共享数的变化
4.1.删除先前生成的共享类数据文件
rm -fv SpringPetclinic.cds*
4.2.重新启动且记录共享类创建日志信息
java -XX:CacheDataStore=SpringPetclinic.cds -Xlog:cds=debug:file=log/cds.log -Dspring.context.exit=onRefresh -jar spring-petclinic-3.3.0-SNAPSHOT/spring-petclinic-3.3.0-SNAPSHOT.jar
4.3.记录生产启动下已经加载类的数量
java -XX:CacheDataStore=SpringPetclinic.cds -Xlog:class+load=info:file=log/class-load.log -jar spring-petclinic-3.3.0-SNAPSHOT/spring-petclinic-3.3.0-SNAPSHOT.jar
4.4.已经加载类的总数
cat log/class-load.log | wc -l
18627
4.5.总共享类文件中加载类的总数
grep -o 'source: shared' -c log/class-load.log
17935
如您所见,93.4% 的类都进入了存档!但 Leyden 不仅仅是加载类。如上所述,存档还存储分析数据和编译的代码。
5.总结
Leyden使得SpringBoot启动和预热时间的初步成果是显而易见的,其他相关的技术如下:
- CDS。这是一个可用于生产的功能,可让您根据设置将启动时间减少高达 54%。
- GraalVM Native Image 支持生成几乎立即启动的本机映像,但可能需要代码重构。
- CRaC 项目是一个 OpenJDK API,可让您将 Java 应用程序的启动时间缩短至几毫秒,并保留 JIT 的强大功能以实现动态性能优化。关于CRaC可以看我以往的博客Java应用-JIT启动预热解决方案及验证结果。