现如今,多少新的概念或产品昙花一现都不足为奇。我们对于一个未知的事物都会感到好奇以及充满期待,就像你突然得知自己要当父亲了,对孩子的降临充满期待一样,也没有哪个父母不希望自己的孩子优秀。
或许你并不期待一个穷人家庭生出来的小孩长什么模样,智商多少,以及他以后能有多大的成就,这些我们都不会去关心。但我想喜欢追星的朋友一定好奇他的偶像的孩子长得像不像他。
这,或许就是主角光环。
Spring Native就是这样一个优秀家庭的孩子,在它还未成熟时,我们意识已经接受了它的优秀,不可否认,它是被它的父亲们怀着远大目标创造出来的,它的未来是已知的。但它是否能取得像Spring Boot一样的成绩还是未知的。
我最近看了一些关于它的热点,一些博主写的文章,但让我感觉到的是,写这些文章的博主或许自己都没了解Spring Native长什么样,就是追个热点,翻译一下国外的视频,或者官方文档,对比下启动耗时、编译耗时、占用内存、编译后的文件体积等参数,所以我从他们的文章中了解不到更多。当然,我也是来蹭个热度的。
很多人都喜欢嘴上夸国产汽车越来越牛了,但行动却很诚实。有一边夸比亚迪N.B,一边掏钱买特斯拉的;有一边夸华为中华有为,一边万把块钱追赶最新款iphone的。所以优秀是一回事,能有什么样的市场反应又是另一回事。
漂亮的姑娘并不一定就抢手,但有趣的灵魂是。
从Spring Native官方文档来看,我是承认它的优秀的,我也会继续关注它,或许将来在合适的项目中去使用它,至少从目前的了解来看,我还不会只为性能买单,一是对现有项目的改造成本略高,二是出于目前项目的成熟度考虑我们还缺少一些云原生组件的支持。
Spring Native出生自带光环,这与当初的Spring WebFlux如出一辙,然而几年过去了,Spring WebFlux有没有流行起来相信大家也有目共睹。难度是WebFlux不够优秀吗?当然不是。我也曾用WebFlux+R2DBC+Lettuce开发过一个消息推送微服务,也用它开发过网关,但我不会使用它来开发业务项目,它的优点不足以让我们忽略它的缺点,所以它在业务开发上注定不会流行起来,现在不会,以后也不会。至于它的优点,别的框架、编程语言难道就没有吗?
https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/
Spring Native provides support for compiling Spring applications to native executables using the GraalVM native-image compiler.
Spring Native 支持使用GraalVM 本机映像编译器将 Spring 应用程序编译为本机可执行文件。
Spring Native使用GraalVM的Native Image编译器在编译期就将JVM字节码编译成可执行镜像文件(机器码),运行在Hotspot虚拟机之外的GraalVM(编译时写入),这说明它为了性能将会抛弃一些运行时特性,如类的延迟加载(常见如远程类加载、tomcat动态部署war)、反射、动态代理、Java Agent。
关于GraalVM:《一文了解GraalVM》https://www.sohu.com/a/375404869_355142
虽然Spring Native可以通过编译期处理方式支持AOP,将动态代理转为静态代理,但并非所有动态代理都能转为静态代理。我记得Dubbo框架中的自适应SPI机制就需要根据请求参数来生成目标代理方法体,这用到了动态字节码技术。同样的,CGLIB也将不支持,这意味着使用CGLIB实现的Bean属性拷贝不能使用,非实现接口的@Async、@Scheduled也将要改成使用接口,反射也需要静态配置。
其次,在微服务中,我们目前使用的一些调用链追踪平台需要借助JavaAgent实现无代码侵入,动态修改类的字节码插入埋点代码后重新加载类的字节码。如果使用Spring Native,这些JavaAgent将会被遗弃,这些调用链追踪平台要么选择支持在编译期完成插桩要么就放弃无代码侵入。
当然,Spring Native的目标是云原生市场,而在云原生占有一席之地的golang也并不支持这类特性,但并阻止不了开发者、组织们拥抱它。而Istio这类目标让流量控制、重试、监控、链接追踪、负载均衡、动态路由下沉到基础设施层的服务网格技术将替代JavaAgent。但…也只是支持进程间的链路,进程内方法的链路就不关心了,但…有必要关心吗?过多的埋点只会影响性能。
随着Service Mesh(服务网关)、FaaS(函数计算,无服务器)技术的发展,相信Spring Native将会被很多组织使用,支持GraalVM Native Image的Spring有着快速启动的特性,更好的支持FaaS,同样体积小构建小的容器镜像也更好的适应云原生,减少运行时内存占用也将为组织减少更多为此付出的成本。
因此,虽然Spring Native在我看来,与Spring WebFlux也很相似,但至少不会是难兄难弟,虽然它们的目标都是提升性能,但WebFlux强行开发者改变现有的编程方式,并有很强的API侵入,注定不会被广泛接受。而Spring Native只是为保持Spring的特性去支持原生镜像,开发者不需要付出很多的学习成本就能接受它。
或许这是一个更直观的比喻,WebFlux更像是Window Phone系统,需要更多开发者与组织的支持来构建生态,而Spring Native更像是鸿蒙系统,采用适配Android应用去继承现有的Android生态,如果不改变主题,你把手机交给身边的朋友,他们不一定看得出这是鸿蒙操作系统。
但即便如此,也有很多未知的因素。
目前也并不只有Spring Native支持GraalVM,与之在同一赛道的还有Quarkus,而且更轻量,然而广大开发者也并没有为此买单,因为它在我们的舒适圈之外,所以Quarkus的流行度并不足以衡量Spring Native的流行度,就像文章前面说的,Spring Native还自带光环。
最后一个不是那么确定的因素,为了性能,你会选择Spring Native还是选择换一门语言如golang呢?我猜选择Spring Native的至少占九层以上,包括我。虽然golang很简洁,但不像java一样能带给我很多惊喜,创造很多“艺术”、艺术。