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插件执行。

spring-boot-native.png

更深入地说,AOT引擎在构建时评估构建环境,以便生成专门为您的应用程序优化后的 application context 和 Spring factories(Spring Boot背后的插件系统)。在实践中,这意味着:

  • 在运行时执行的 Spring 基础结构更少
  • 在运行时要判断的条件更少
  • 减少反射,因为使用的是编程式bean注册

AOT 引擎根据标记为活动的 Bean、Spring 编程模型的知识以及与 Spring Native 捆绑在一起或由应用程序本身提供的native hint,来推断出将应用程序编译为本机可执行文件所需的native configuration。

aot-architecture.png

我们要特别感谢 Stéphane Nicoll 领导了这个新的AOT引擎的设计和实现。

减少内存占用

AOT 引擎的一个关键优势是,基于它的原生可执行文件占用的内存更少,因为native configuration更准确,反射使用得更少,运行时需要的 Spring 基础结构更少。

Spring Native 0.11与Spring Native 0.10相比,平均减少了 20%26% 的内存占用!下图显示了几个示例应用程序的数据:

native-rss.png

启动速度更快

与0.10版本相比,Spring Native 0.11的启动时间快了 16%35% ,因为某些处理逻辑已经从运行时转移到了编译时。Spring Boot和Spring Framework的内部架构还有微调的空间,因此这部分仍有改进的余地。

native-startup.png

兼容性改进

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 提前创建一个类代理:

public class ScopeNativeConfigurationProcessor implements BeanFactoryNativeConfigurationProcessor {
  @Override
  public void process(ConfigurableListableBeanFactory beanFactory, NativeConfigurationRegistry registry) {
    new BeanFactoryProcessor(beanFactory).processBeansWithAnnotation(Scope.class, (beanName, beanType) -> {
      Scope scope = beanFactory.findAnnotationOnBean(beanName, Scope.class);
      if (scope.proxyMode() == ScopedProxyMode.TARGET_CLASS) {
        registry.proxy().add(NativeProxyEntry.ofClass(beanType, ProxyBits.NONE,
        ScopedObject.class, Serializable.class, AopInfrastructureBean.class));
      }
    });
  }
}
复制代码

NativeConfiguration扩展点已经过优化,可以通过NativeConfigurationRegistry来提供 API:

public interface NativeConfiguration {
  default boolean isValid(AotOptions aotOptions) { return true; }
  default void computeHints(NativeConfigurationRegistry registry, AotOptions aotOptions) { return; }
}
复制代码

这些扩展点是定义在 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% 的内存占用。

jvm-rss.png

AOT模式还将应用程序启动速度提高了 3%24%

jvm-startup.png

请注意,到目前为止,我们还没有特别关注传统 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和原生可执行文件支持。

boot3-aot-architecture.png

我们与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社区的成员一起庆祝这个发布!


本文首发于robberphex.com/new-aot-eng…,本文翻译自spring.io/blog/2021/1…

猜你喜欢

转载自juejin.im/post/7041168772924702750