今天和大家聊一聊,为什么我觉得Spring依然会是云原生时代的优秀平台之一。时间回到2015年,我在华盛顿参加SpringOne2015大会,主题演讲是CloudNativeEnterprise。那个大会的口号也是CloudNative,铺天盖地的海报都跟CloudNative有关。你可能会疑惑,那个时候容器还没有流行起来,你怎么敢叫它云原生呢?虽然很多同学对云原生的理解可能不尽相同,但越来越多的人认为“云原生是文化,不是容器”。可以肯定的是,云原生不等于容器。这是一种软件开发文化。即使有Serverless或者基于V8隔离的WebAssemblyFaaS平台,也属于云原生的范畴。在云原生的趋势下,Spring做了很多事情,比如支持分布式架构的SpringCloud,基本上是分布式和基于云的Java应用的必备框架。每个云厂商都有SpringCloud的对接版本,如SpringCloudAlibaba、AWS、Azure、GCP等。SpringCloud大大简化了Java应用程序与云服务的连接。可以说,在微服务越来越流行的过程中,Spring生态一直处于领先地位。很多人可能会疑惑:我们之前都知道Spring的成就,但是这两年好像没有什么发展。Spring能否继续引领技术潮流?其实之所以会产生这样的疑惑,是因为我们在基于云和云原生环境进行开发的时候,一般都比较注重技术栈的选择,而这背后主要是成本的问题。每个开发者或者中小型公司都希望购买更少的云资源来做更多的事情,其中??最重要的就是内存和CPU。内存消耗要求小。如果可以编译成独立的可执行程序,尽量选择一些轻量级的开发框架;并考虑语言高效和完全异步的框架,可以保证CPU的充分利用,避免线程等待。浪费。综合来看,很多人更倾向于选择Rust、Node.js、Golang等技术栈。但是,Java启动慢,内存消耗大。好像比较贵,好像不太适合下一个云原生时代。那么,作为基于Java语言的Spring生态,它是否还能适应新的开发方式,如CloudNative、Serverless、Faas等,是否还会是云原生时代最好的平台选择呢?接下来我将从5个角度为大家分析这个问题,分别是:Java和JDK的发展,充满良性竞争的JVM语言,成熟的面向服务架构SpringBoot和SpringCloud,以及Spring使事件驱动架构更易于使用的反应式。一、Java和JDK的发展我们知道Spring是基于Java框架的,而JDK是运行Java程序的基础。讨论“Spring是否会成为云原生最好的平台之一”这个问题,首先要看JDK基础如何,能否为Spring的发展提供良好的基础,跟上时代的步伐。次。首先是版本迭代。现在OpenJDK的开发速度非常快。以前三年出一个大版本,现在半年出一个版本。很多同学感叹现在都快Java17了,自己还在用Java1.8。我们都说软件开发需要小步跑。这是一个很好的开发方式:小步骤、快速反馈、快速迭代开发。同样,JavaScript每年一个版本,TypeScript每年三个版本,Java每年两个版本。可以说都是非常不错的节奏。二是JDK特性的更新。如果你关注JDK,不难发现JDK中集成了越来越多的特性,比如类似coroutines的轻量线程Loom项目,改进Native调用支持的Panama项目(SIMD支持),以及更高级的GC算法等。针对我们前面提到的Java启动慢、内存消耗大的问题,Oracle推出了基于OpenJDK的GraalVM,可以直接在JVM中运行JavaScript、Python、Ruby等语言。它是名副其实的PloyglotJVM。此外,GraalVM还提供了NativeImage特性,可以将Java代码转换为独立的可执行程序。Spring还推出了SpringNative项目,可以非常方便的对SpringBoot应用进行native-image,让Spring应用启动更快,消耗内存更少。原生镜像的Spring应用可以满足每一位开发者或中小企业“低成本上云”的需求。即使是Java命令行应用,GraalVM也有非常好的解决方案——Picocli+GraalVMNativeImage+upx,可以将Java应用编译成更方便的可执行程序。下图是GraalVM多语言和NativeImage支持列表,如下:此外,各个云厂商也在积极开发JDK,比如AliJDK、AmazonCorretto、Azul等,对JDK的开发。所以对于Spring来说,JDK的基础还是很扎实的。2、充满良性竞争的JVM语言JDK不仅支持Java作为一种编程语言,相反,它可以支持多种语言,如Kotlin、Scala、Groovy等,这里我们统称为JVM语言。眼下,JVM语言处于一种良性竞争的状态。我们知道每种语言都有自己的使用场景。云原生时代,多语言开发支持非常重要,开发者需要根据实际业务场景选择不同的开发语言。无论是JVM语言还是GraalVM支持的语言,都可以直接与Spring集成,方便开发者充分利用Spring技术栈进行开发。其中对Spring支持最好的语言是Kotlin。Kotlin和Spring的集成已经渗透到框架的方方面面,比如SpringBoot和Kotlin的集成,SpringWebflux对KotlinCoroutines&Flow的支持,SpringData,SpringIntegration,SpringCloudFunction等也包括对Kotlin,这一切都实现了与Kotlin深度融合的目的,就是让语言和框架更好的结合,提高开发效率。此外,Kotlin和Scala也是与Spring结合良好的语言。因为Java、Kotlin和Scala这三种语言在Spring中融合的非常好,接下来我会详细讲解,帮助大家对JVM语言的发展现状有更清晰的认识。JavaJava语言的发展还是非常快的。随着OpenJDK的发展,Java每六个月就会推出一个版本。每个版本都会伴随语法升级、标准库升级等,极大方便了开发者。从Java9到16,完成了很多语法和特性的改进,比如大家都知道的var关键字(局部变量类型推导)、Textblock、PatternMatchingforinstanceof、Record、sealedinterface等。虽然Kotlin说Kotlin是不完全是针对JVM,它还包括Native、JavaScript等,但是Kotlin对JVM和Android的支持是目前众多Kotlin平台中功能最丰富和最稳定的。现在Kotlin发展非常迅速,孵化了几个子项目,比如最新的KotlinMultiplatformMobile(一套代码支持多移动平台),KotlinComposeforDesktop(一套代码开发多操作系统桌面应用)),ETC。。当然,这些变化中最引人注目的是Kotlin1.5推出的Kotlin中间表示(IR)。借助新的IR,可以将Kotlin代码编译输出到各种目标平台,程序也更加完善,比如大家关心的KotlinWebAssembly。.ScalaScala2发布于2006年3月,已经是很久以前的事了。好消息是Scala3.0将于2021年5月发布。虽然Scala3添加了新功能,但它从Scala2中删除了一些晦涩的功能,以使Scala更易于使用。有兴趣的可以关注一下Scala3的官网。Scala3的另一个核心变化是编译器的调整。名字叫TASTy,是TypedAbstractSyntaxTrees的缩写。结构如下:在TASTy的帮助下,已经有了Scala.js。Kotlin和Scala都对函数式编程非常友好,在这一点上都弥补了Java的不足。此外,Kotlin和Scala还支持JavaScript编译输出,这对基于V8的Serverless平台非常有帮助,比如Cloudflare的Serverless平台。此外,Kotlin和Scala也在积极探索对WebAssembly的支持,这对于支持Web开发来说是个好消息。当然,还有很多其他的JVM语言,比如Groovy、Clojure等,也在积极发展中。这些JVM语言相互竞争,相互学习。这对开发者来说是一个非常好的消息。Spring依赖的JDK和JVM语言说完了,接下来说说Spring中两个非常成功的项目,SpringBoot和SpringCloud。SpringBoot和SpringCloud是两个非常成功的项目,基本上都是基于Java技术栈的互联网公司在使用。另外,如果你最近关注过Spring顶级布道者JoshLong的演讲,你会发现他一直在谈论SpringReactive,而且他还写了一本书,名叫《Spring Reactive》。那么为什么SpringBoot、SpringCloud和SpringReactive会引起如此多的关注呢?我们知道对于云原生来说,有两种非常重要的架构方案,一种是面向服务的架构,一种是事件驱动的架构。面向服务的体系结构通常基于同步请求/响应模型。SpringBoot和SpringCloud的目标就是支持这个特性;事件驱动架构基于异步消息模型和消息路由,SpringReactive项目的核心就是支持这种结构。下面就带大家看看Spring是如何支持云原生中这两种重要的架构方案的。这样,你也就对Spring中的三个重要项目SpringBoot、SpringCloud和SpringReactive有了一个了解。更清晰的认识。3.面向服务架构成熟的SpringBoot和SpringCloud通常,云原生应用倾向于微服务设计,而微服务设计的核心内容是面向服务的架构设计和应用编程接口(API)管理。Boot和SpringCloud的目标就是支持这个特性,而且这两个项目都非常成功,基于Java技术栈的互联网公司基本都在用。我们知道,服务接口最典型的结构就是Request/Response模式,尤其是WebRequest/Response模式。当然远程RPC的request/response也属于这一类,比如HTTPREST、gRPC和Dubbo。对应Spring中面向服务的架构设计,SpringMVC可以很好的支持Web和HTTPRESTAPI,包括对OpenAPI的支持。其他的RPC通信也有相应的SpringBootstarter支持,SpringBoot也有相应的starter组件支持,开发起来也很方便。如果想暴露其他形式的服务,比如WebService、SOAP等传统服务形式,也可以使用SpringWebServices(spring-ws)项目。另一个特性API管理,主要涉及服务治理和服务消费者调用,对应的核心技术栈主要是SpringCloud项目。SpringCloud为面向服务的架构和API管理提供了多种基础设置,比如服务注册发现、复杂平衡、APIGateway、断路器保护等,这些技术栈方便了我们更好的管理和管理服务,也让消费者可以更好地呼叫服务。综上所述,面向服务的架构和API管理分别对应SpringBoot和SpringCloud技术栈。典型架构如下:如果你的架构是面向服务的,比如涉及到服务编排、服务治理、API网关,那么SpringCloud会是一个非常好的选择,功能完备、框架稳定、文档完善、个人实践如阿里巴巴。如果你的公司是基于Java技术栈,那么SpringCloud是实现微服务架构的最佳支撑和实践。阿里巴巴自2018年7月开始开源SpringCloudAlibaba,截至目前,已经获得超过19000颗星,超过所有其他实现的总和。从X-lab开放实验室发布的《2020年微服务领域开源数字化报告》中,我们也看到SpringCloudAlibaba已经成为最活跃、最受开发者欢迎、最完整的SpringCloud实现工具链。每个人都可以在选择过程中考虑。4.SpringReactive,让事件驱动架构更易用。前面我们介绍了Spring对面向服务架构的支持,还有另外一种架构模型,就是事件驱动架构。事件驱动架构被普遍认为是云原生的首选架构方案,那么Spring是如何支持这方面的呢?这就涉及到了SpringReactive项目,其核心是支持事件驱动架构。SpringReactive是面向异步消息的。消息或事件是企业集成模式(EIP)的第一个架构模式。你可能听说过SpringIntegration(SpringIntegration)项目,它主要负责企业集成。SpringReactive的目的是让事件驱动的架构设计成为应用架构的首选,而且应该更简单。这里扯个题外话:我和一些资深的SpringBoot和SpringCloud程序员交流过。各种服务接口的设计大家都很熟悉,甚至包括代码层面的细节,但是说到企业集成模式(EIP),他们都说这是MartinFowler家喻户晓的杰作,问是否你的系统用了ApacheCamel或者SpringIntegration,大家都说面向服务的架构满足了业务需求。那么这里有一个问题,为什么这么知名的EIP、ESB或者EDA在架构设计上没有采用呢?是被人遗忘在灯光下,还是门槛太高,又或者根本就是纯理论,完全脱离实践?在面向服务的现代化架构设计中,基本都是基于服务接口调用,而且调用是同步的,所以服务编排和API管理起到了非常重要的作用。当然,在面向服务的架构设计中,我们也会引入一些消息驱动的设计,借助Kafka或者其他MQ系统,来处理一些异步或者数据分析的场景,比如用户注册后发送邮件,以及用户登录时触发事件安全审核后触发搜索引擎的增量索引,产品信息或价格变动,用户下单后触发各种通知等。面向服务有它的好处,但是需要解决很多问题,比如非阻塞、服务注册和发现、高性能、易集成等。这也是为什么很多专家提出在云原生场景中,event-驱动架构是主流。事件驱动架构不涉及这些负责机制的服务注册和发现,基于消息的路由也很容易,异步消息通信的性能更高(当然你的账单更小),各种SaaS服务集成更简单(EventBridge产品),轻松触发FaaS等等,想了解更多的可以看这本书?。这里是Redhat推荐的基于微服务思想的事件驱动架构设计,如下图:从这张图中我们可以看出,所有系统之间的交互都是通过消息来沟通的,微服务不再是面向接口的request/Response设计句柄Request/Response来自不同应用程序的请求,但以异步的方式不断处理来自Broker的消息。说到这里,大家可能会明白,如果说CloudNative是基于事件驱动的设计架构,那么SpringReactive的目的就是让事件驱动的架构简单易用,易于开发。这就是SpringBoot和Cloud对面向服务架构的支持。一样的。另外,这两种架构并不矛盾,它们可以共存,互为补充。要实现更好的事件驱动架构,两个基础不可或缺:异步和消息传递。异步可以解决线程等待的问题,消息及其路由可以实现应用的松耦合。目前越来越多的产品采用异步消息方案。各种消息产品的中间件就不用多说了,大家熟知的HTTP/2就是基于异步消息通信的。那为什么要异步呢?我们知道消息处理模型不同于同步服务调用。比如消息处理的EventLoop和Actor模型,都是非常高效的消息处理方式。如果我们在处理消息的过程中,还可以基于线程池来处理同步服务调用,这势必会影响模型和性能。当然,完全没有同步也不是不可以,但是尽量避免同步服务调用过多的场景。Spring围绕异步和消息场景要做很多工作,而我们都知道Java对异步的支持非常滞后。Java1.8增加了CompletionStage接口,Java9增加了ReactiveStream支持并介入了Flow。大家一直关注的轻量级线程的Loom项目还在开发中,预计要到Java17才会发布。因此,目前大部分的Java项目都会选择Reactive框架。当然,Spring团队开发了Reactor框架,加入了Reactor对Netty、Kafka等的适配,从底层保证它是异步的,所以这也是SpringReactive这个名字的由来。.接下来就是大家看到的一幕了。SpringWebflux、SpringIntegration、SpringData和许多其他项目都添加了对异步的支持。所有这些调整都是为了保证它与底层完全异步。你可以理解为5G有非独立组网和独立组网两种方式,但是Spring选择了Reactive这种独立组网和独立生态的方式。当然,工作量也很大。这涉及到两个非常大的问题:数据库和分布式通信。目前大部分NoSQL产品都提供了异步接口,异步访问NoSQL产品是没有问题的。NoSQL虽然发展迅速,但依然没有撼动数据库的地位。我们都知道Java中访问数据库的标准是JDBC,但是JDBC是一个同步接口,所以Spring推出了R2DBC项目,目的是通过Reactive异步接口访问数据库目前JDBC和R2DBC的使用心得Spring框架下几乎是一样的。在这里和同学同步两条消息:Spring5.3内置了R2DBC支持,即spring-r2dbc,与spring-jdbc并列。大家喜欢用的MySQL数据库也推出了mariadb-r2dbc1.0.0稳定版,Oracle也推出了R2DBC版驱动。当然Java中的DB框架、SpringJPA、MyBatis等都对R2DBC做了适配。Hibernate还推出了hibernate-reactive项目(基于Vert.x数据库)。虽然它不是基于R2DBC,但它也是完全异步的。另一个问题是分布式通信,它在微服务架构中起着非常重要的作用。Spring一直主要支持HTTP,但是HTTP协议主要是为浏览器设计的,后端服务之间的通信优势不明显,在性能上没有优势。当然,基于HTTP/2异步消息通信的gRPC是一个不错的选择,但是Spring一直没有内置gRPC支持。当然,这对大多数开发者来说不是什么大问题。第三方的grpc-spring-boot-启动器也做得很好。如果你关注过Spring的发布,应该知道Spring5.2后续版本选择了RSocket通信协议,将RSocket构建到spring-message项目中。为什么?RSocket是一种完全异步的二进制消息通信协议,提供了完整的通信模型,是点对点通信,与事件驱动架构非常匹配。这就是SpringReactive将RSocket合并到Spring核心中的原因。当然,在背后的开发中,RSocket、Spring和阿里团队是唱主角的。CNCF下有一个CloudEvents规范,主要解决异构系统的事件通信。消息和事件在数据结构上是一致的,都是Headers和Payload(数据)结构,都包括消息头的扩展。最新的cloudevents-javaSDK2.1,Springmessaging增加了对CloudEvents的支持,同时也支持对CloudEvent接口的codec支持,统一整合消息和事件,让Spring处理CloudEvents和消息变得更加简单。企业集成相关的产品,如ApacheCamel、基于Akka的Alpakk、MuleSoft的Mule4、SpringIntegration等,这些产品都提供了与Reactive的集成,可以与SpringReactive无缝对接。五、总结回到文中的问题,为什么Spring仍然是云原生时代最好的平台之一?综上所述,Java和JDK发展得很好,JVM语言良性发展,充满竞争。成熟的SpringBoot和SpringCloud让面向服务的架构设计变得简单易用,而SpringReactive让事件驱动的架构更加简单易用,同时让更多的企业系统与SpringReacitve完成对接,无论是是物联网设备、ESB产品、SaaS或云服务等。针对微服务场景,SpringCloud提供了成熟的面向架构的服务基础,而SpringReactive是面向未来的事件驱动架构。当然,这并不意味着面向服务的架构已经过时了。事实上,面向服务的架构是非常成功的。然而,在云原生或新的无服务器环境中,事件驱动架构可能更合理,或者两者结合。不用担心,Spring在这两方面都做得很好。
