Spring Native 0.11发布,带来新的AOT引擎和性能优化
Spring Native 0.11已于2021年12月9日发布。
这个宏大的版本是Spring团队五个月辛勤工作的结果,他们一直在研究一个全新的架构,将让Spring使用GraalVM创建原生可执行文件的方式提升到一个新的水平。你目前已经可以已经在start.spring.io上试用了!
想了解有关Spring Native 0.11的更多信息,可以查看来自Spring布道师的新一期的Spring Tips视频(在YouTube上)。
新的AOT引擎
这个版本最大的变化无疑是引入了新的AOT引擎,该引擎在构建时对Spring程序进行深入的转化和分析,并生成所需的GraalVM Native配置。这些转换由Maven和Gradle Spring AOT插件执行。
更深入地说,AOT引擎在构建时评估构建环境,以便生成专门为您的应用程序优化后的 application context 和 Spring factories(Spring Boot背后的插件系统)。在实践中,这意味着:
- 在运行时执行的 Spring 基础结构更少
- 在运行时要判断的条件更少
- 减少反射,因为使用的是编程式bean注册
AOT 引擎根据标记为活动的 Bean、Spring 编程模型的知识以及与 Spring Native 捆绑在一起或由应用程序本身提供的native hint,来推断出将应用程序编译为本机可执行文件所需的native configuration。
我们要特别感谢 Stéphane Nicoll 领导了这个新的AOT引擎的设计和实现。
减少内存占用
AOT 引擎的一个关键优势是,基于它的原生可执行文件占用的内存更少,因为native configuration更准确,反射使用得更少,运行时需要的 Spring 基础结构更少。
Spring Native 0.11与Spring Native 0.10相比,平均减少了 20% 至 26% 的内存占用!下图显示了几个示例应用程序的数据:
启动速度更快
与0.10版本相比,Spring Native 0.11的启动时间快了 16% 到 35% ,因为某些处理逻辑已经从运行时转移到了编译时。Spring Boot和Spring Framework的内部架构还有微调的空间,因此这部分仍有改进的余地。
兼容性改进
AOT引擎也更加精确,因为它没有试图分析Spring annotation或其他类型信息来重复Spring在运行时所做的事情。相反,它fork一个新进程,在编译时创建并内省、探测 application context (在不启动应用程序的情况下)。这允许利用部分Spring Framework在运行时所做的工作,并在 bean 定义级别上工作,这比原来精确得多。
运行时的灵活性
在编译时执行这些优化意味着运行时灵活性低于常规的 Spring Boot 自动配置模型。例如,在运行已编译为原生二进制的 Spring Boot 应用程序时,仍然可以更改应用程序的 HTTP 端口或日志级别,但不能在运行时使用配置文件来添加新的 Bean。
这就是为什么在JVM上,AOT模式仅仅是一种可选的运行模式,而不是唯一的运行模式。如果AOT符合您的需求,你就可以使用这种优化。在原生模式下(根据设计,此时运行时的动态性要低得多),AOT是强制性的。此外,请记住,目前运行环境是在编译时探测的。我们可能会在未来让这种探测更加灵活,以便它适合大多数用户场景。
扩展点
新的AOT引擎提供了一个可插拔的模块化架构,用户(如开发者或Spring项目团队)可以使用它来支持各种新功能。
比如,可以看看BeanFactoryNativeConfigurationProcessor
的扩展点实现,它会自动为注释为带有 @RequestScope
或 @Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
的 bean 提前创建一个类代理:
1 | public class ScopeNativeConfigurationProcessor implements BeanFactoryNativeConfigurationProcessor { |
NativeConfiguration
扩展点已经过优化,可以通过NativeConfigurationRegistry
来提供 API:
1 | public interface NativeConfiguration { |
这些扩展点是定义在 META-INF/spring.factories
中的,因此您可以定义自己的扩展点。
AOT 测试支持
Spring Native 0.11中的一个非常重要的部分是实现对AOT代码路径的测试支持,以便将 Native 模式的测试支持提升到一个全新的水平。让Spring Native兼容性显著提高,支持更多种类的测试。
结合Native构建工具,它允许您运行Spring Boot,Spring Framework或普通的JUnit测试,就像在JVM上一样。
与Spring无关,Mockito目前还不支持支持,但目前Mockito开发者仍然在做类似的工作,以便Mockito将来能够在AOT模式下工作。
传统 JVM 上的 AOT
在将在JVM上运行的应用程序上执行AOT转换有两个关键好处。
第一个是能够轻松调试将在IDE中的JVM(主应用程序或测试)上运行的代码。
第二个优点是效率更高。目前,它可以减少约 4% 到 17% 的内存占用。
AOT模式还将应用程序启动速度提高了 3% 至 24% 。
请注意,到目前为止,我们还没有特别关注传统 JVM 上的AOT效率,因此在以后的版本中很可能有机会进行进一步改进。
Bellsoft Liberica NIK
Bellsoft Liberica Native Image Kit (NIK)是一个基于GraalVM开源代码和Liberica JDK的Native Image编译器发行版。从Spring Native 0.11开始,它默认用于Buildpacks的native模式,这与JDK模式一样,都默认使用Liberica JDK。也可以通过使用SDKMAN安装或手动下载安装。
今年早些时候,Buildpacks团队宣布,使用Liberica Native Image Kit的VMware客户可以将其Spring应用程序作为原生可执行文件运行,并确认它们会得到完全的支持。
新的基线
Spring Native 0.11也让我们有机会提供基于Spring Boot 2.6的新基线。
- GraalVM 21.3提供了对Java 11和Java 17的支持,并利用有条件的Native 配置和其他相关的改进来允许占用更小的内存占用,并对JVM生态提供更好的Native模式支持。
- 不再提供Java 8版本的GraalVM,因为它太老了,无法进行合理的维护,但您仍然可以使用Java 11版本的GraalVM编译大多数Java 8应用程序。
- 支持 Native Build Tools 0.9.8,我们将继续合作来完善和改进它。
Spring Boot 3 将原生支持 Native 模式
Spring Native 0.11为Spring Boot提供了成熟的Native模式。Spring团队现在可以专注于下一个主要步骤:作为Spring Framework 6、Spring Boot 3和相关组合项的一部分,改进Native模式的支持。
请记住,在Spring Native上所做的一切工作都是与其他Spring项目密切合作完成的,但没有进行深层的架构修改。
随着AOT和Native模式成为Spring Boot 3和Spring Framework 6的主要主题,这些特性的质量、可维护性和易用性将达到一个新的水平。
AOT引擎将被改进并直接集成到Spring框架中。其他项目,比如Spring Data或Spring Security,将能够在其范围内提供Native模式的支持(并对其进行测试),而Spring Boot将在其插件和文档中提供开箱即用的AOT和原生可执行文件支持。
我们与GraalVM团队和JVM生态的协作将会增加,以便为Spring之外的各种三方库提供 Native configuration,要么直接在那些三方库中,要么在 Native Build Tools 附带的 Native configuration代码库中。
我们计划在 Spring Boot 3 milestone 2 版本开始提供开箱即用的GraalVM Native模式支持,预计在2022年3月下旬发布,并利用上在Spring native上的工作成果。
Spring Boot的Native模式计划于2022年底全面启用。
Spring Native有很多令人兴奋的计划,但现在,让我们花些时间与Spring社区的成员一起庆祝这个发布!
本文翻译自https://spring.io/blog/2021/12/09/new-aot-engine-brings-spring-native-to-the-next-level。
Spring Native 0.11发布,带来新的AOT引擎和性能优化
https://robberphex.com/new-aot-engine-brings-spring-native-to-the-next-level/