领先一步
VMware 提供培训和认证,助您加速进步。
了解更多Spring 团队刚刚发布了 spring-graalvm-native 项目的 0.6.0 版本。该项目旨在让任何试图构建其 Spring 应用程序的 GraalVM 本机映像的人更容易上手。
有关 Spring 本机映像的深入了解,请参阅 Sébastien Deleuze 的 Devoxx 演讲。
在这篇博文中,我们将讨论自那时以来发生的变化,并为您指出一些关键资源,使您能够尝试它!该项目位于 spring-projects-experimental github 组织中,表明它仍在开发中,但我们有许多示例应用程序展示了已经可用的技术类型,以及大量关于如何使用您自己的应用程序进行试验的文档。
快速回顾一下,GraalVM 是一个伞形项目,可用于多种目的,但我们此处要关注的关键方面是将 JVM 代码作为本机映像运行。一旦编译成特定于平台的本机映像,应用程序应具有非常快的启动速度和更可靠的内存配置文件(没有 JIT 在开始时导致内存峰值)。
创建映像时,本机映像构建工具需要了解您的应用程序信息,例如加载了哪些资源、可能正在反射哪些类型,以及类型是在映像构建时安全初始化还是必须在运行时稍后初始化。此信息使本机映像工具能够尝试为应用程序构建最佳映像。
实际上有几种收集和通信此配置的方法
这些计算配置的方法各有利弊。例如,代理只能收集应用程序运行时执行的代码路径上的信息,但它肯定会创建一套精确所需(在资源/反射访问方面)的最佳配置。另一方面,该功能不会创建完全最佳的配置,因为它不运行应用程序,因此必须允许某些可能或可能不采用的代码路径,但作为构建过程的一部分,该功能可以执行 Spring 特定的优化,例如急切地评估条件配置。当本机映像构建运行时,已知完整的类路径,因此可以在那时执行 @ConditionalOnClass 检查,如果它们失败,则可以丢弃该配置,甚至在生成的映像启动时也不再查看。
我们一直在这些方面努力工作,试图改善生态系统,以便我们能够走向一个一切都能正常工作的世界。还有很长的路要走!我们正在深入研究 Tomcat,以使其配置像 Netty 一样容易获取。与 GraalVM 团队一起,我们一直在确保 Spring Boot 应用程序中没有任何会阻碍本机映像构建的东西(需要双方进行修复),并改进 spring-graalvm-native 功能以更好地理解更广泛的 Spring 应用程序。我们还一直在帮助确保代理收集器没有遗漏任何东西。我们目前正在与 GraalVM 团队一起解决的问题实际上在此处跟踪。
自 Spring One Platform 2019 和 Devoxx 的演示以来,该功能对 Boot 了解更多,代理遗漏更少,GraalVM 兼容性更高,生成的映像大小减小,映像构建时间缩短,我们甚至包含了更多示例项目来演示正在工作的内容。
这里有许多示例项目此处,甚至包括一个 PetClinic(当然!)以及此处的示例相关文档,介绍如何使用它们。有使用 Netty、Tomcat、Spring MVC、Spring WebFlux、JPA、Spring Cloud Function、Kotlin 等的示例。您可能会看到什么?
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot ::
...
INFO: Started TomcatApplication in 0.044 seconds (JVM running for 0.62)
对于将其应用于您自己的项目,文档描述了所有步骤,无论是使用该功能、代理还是涉及两者的混合模式来运行它。混合模式有时是两全其美的方法,因为代理可以捕获功能可能遗漏的东西,反之亦然。
这个过程还没有完全顺畅,许多领域仍有待改进。负责该功能的团队和 GraalVM 团队都在努力改进诊断,以便当出现问题时,您仍然可以取得进展并了解下一步该怎么做。某个随机应用程序第一次就正常工作的可能性不大,但对于致力于解决问题的任何人来说,许多应用程序都将正常工作。您的应用程序可能正在使用我们测试中尚未遇到的库。它可能正在使用该功能尚未了解的 Spring 行为。它可能在映像构建时或在编译映像启动时的运行时出错。有一故障排除页面,讨论了一些常见问题以及如何解决它们。遇到其他问题?请在项目上提出问题。
在 spring-graalvm-native 项目中有一个配置子项目,它试图以易于扩展的形式封装关于 Spring Boot 行为的知识。例如,它编码了一个特定的导入选择器可能需要对特定类型进行反射访问。该功能本身由这种封装的知识驱动,如果您发现知识目前不足,请随时增强它并贡献回项目以扩展该知识,请参阅可扩展性指南。
spring-graalvm-native 项目中还包含一些替换项,替换是 GraalVM 的一个术语,指在映像构建时对现有类进行更改,该现有类当前在本机映像中包含时无法正常工作。随着时间的推移,计划仍然是消除这些替换项,并与包含这些有问题类的项目合作,使它们达到可以在本机映像内部或外部工作的理想形式。
尽管 spring-graalvm-native 专注于 Spring,但显然 Spring 项目通常包含许多第三方依赖项。其中许多尚未包含必要的配置,因此我们的功能正在尽力“弥补”它们。在可能的情况下,我们的计划仍然是与这些依赖项提供商合作,帮助他们制作理想的本机映像配置,然后它将简单地由本机映像构建自动获取。GraalVM 代理提供了一种很好的方法来尝试处理缺少配置的代码。
所有工作都只发生在这个实验性功能中吗?远非如此。Spring 中已经进行了一些增强,以确保它在构建成本机映像时正常运行。例如,在 Spring Framework 中,Spring Framework 5.2 中的 @Configuration proxyBeanMethods 属性使应用程序无需 CGLIB 代理即可运行(本机映像过程只能支持 JDK 代理)。我们还在 Spring Boot 条件处理中重构了一些类加载,以使用不同的方法,因为代理无法捕获原始的加载形式。
更多这样的增强功能将陆续推出。还有更多东西需要教给该功能,而在核心 Spring 中,启动时仍有太多工作可以推到构建时,这将严重影响构建的本机映像的内存需求。这些改进不仅会使构建成本机映像的应用程序受益,还会使在常规 JVM 上运行的应用程序受益。情况只会越来越好!感谢 GraalVM 团队在此工作中对我们的支持。要跟踪我们的进展,请关注该项目。