简介: 基于Java语言的Spring生态,还是否适应新的开发方式,比方Cloud Native、Serverless、Faas等,它还会是云原生时代的最佳平台的抉择吗?本文将从5个角度来为你剖析一下这个问题,别离是:Java和JDK的倒退、充斥良性竞争的JVM语言、成熟的面向服务架构的Spring Boot和Spring Cloud、让事件驱动架构更易使用的Spring Reactive。

作者 | 雷卷
起源 | 阿里技术公众号

大家好,我是陈立兵,花名雷卷,Java/Kotlin工程师、 Alibaba RSocket Broker开发者Reactive基金会的初创成员。目前次要关注于Reactive/RSocket、Serverless、WebAssembly、 Deno/Rust等相干技术。

明天和大家聊聊为什么我认为Spring依然会是云原生时代最佳平台之一。

工夫回到2015年,过后我在华盛顿参加SpringOne 2015大会,主题演讲是Cloud Native Enterprise。那次大会的口号也是Cloud Native,铺天盖地的海报都与Cloud Native无关。

你可能会感到奇怪,那个时候容器还没有风行啊,怎么就敢称为Cloud Native呢?尽管不少同学对Cloud Native的了解可能不太一样,然而越来越多的人置信“Cloud native is about culture, not containers”。能够必定的是,云原生不等于容器,它是一种软件开发的文化,即使后续有基于V8隔离的Serverless或者WebAssembly FaaS平台,也还是云原生的领域。

而在云原生的潮流下,Spring做了很多事件,比方反对分布式架构的Spring Cloud,它根本是Java利用分布式和云化的必备框架,各个云厂商都有Spring Cloud的对接版本,比方Spring Cloud Alibaba、AWS、Azure、GCP等,Spring Cloud极大地简化了Java利用和云服务的对接。

能够说,在微服务逐步风行的过程中,Spring生态始终处于领先地位。很多人可能会纳闷:Spring之前获得的这些成就咱们都晓得,可这两年如同并没有什么倒退,Spring还能持续引领该技术趋势吗?

其实,之所以会有这样的纳闷,是因为当咱们谈到基于云和云原生环境的开发时,广泛更关注的是技术栈的抉择,而这背地次要是费用的问题。

每一位开发者或中小公司都心愿购买更少的云资源干更多的事件,其中最次要的是内存和CPU。内存耗费要求小,如果能编译为独立可执行程序,就尽量抉择一些轻量型的开发框架;而且要思考语言高效且全异步化的框架,这样能够保障充分利用CPU,防止线程期待等造成的节约。

综合来看,很多人会更偏向于抉择Rust、Node.js、Golang等技术栈。而Java启动慢,耗费内存多,如同还比拟费钱,看起来曾经不太适宜接下来的云原生时代。

那么作为基于Java语言的Spring生态,还是否适应新的开发方式,比方Cloud Native、Serverless、Faas等,它还会是云原生时代的最佳平台的抉择吗?

接下来,我将从5个角度来为你剖析一下这个问题,别离是:Java和JDK的倒退、充斥良性竞争的JVM语言、成熟的面向服务架构的Spring Boot和Spring Cloud、让事件驱动架构更易使用的Spring Reactive。

一 Java 和 JDK的倒退

咱们晓得Spring基于的是Java框架,而JDK又是运行Java程序的根底。要探讨“Spring还会不会是云原生的最佳平台之一”这个问题,咱们须要先来看看JDK这个底座怎么样,是不是能为Spring与时俱进的倒退提供良好的根底。

首先是版本迭代。当初OpenJDK的开发速度十分快,之前是三年出一个重大版本,当初半年就出一个版本。好多同学感叹当初都快Java 17了,而本人还在用Java 1.8。咱们都说软件开发要小步快跑,这个是一个好的开发方式:小步快跑、疾速反馈、疾速迭代开发。相似的还有JavaScript一年一版,TypeScript一年三版,Java一年两版,能够说都是十分好的节奏。

其次是JDK个性的更新。如果你关注JDK的话就不难发现,越来越多的个性被融入到JDK中,比方相似协程的轻量级线程Loom我的项目、晋升Native调用反对的Panama我的项目(SIMD反对)、更高级的GC算法等。

而针对咱们后面提到的Java启动慢、耗费内存多的问题,Oracle推出了基于OpenJDK的GraalVM,它能够间接在JVM中运行JavaScript、Python、Ruby等语言,是货真价实的Ployglot JVM。另外,GraalVM还提供了Native Image个性,能够将Java代码转换为独立可执行程序。Spring也推出Spring Native我的项目,能够十分不便将Spring Boot利用native-image化,这样Spring利用启动的速度更快,耗费的内存也更少。native-image化后的Spring利用就能够满足每一位开发者或中小公司对“上云且费用更少”的需要。即使是Java的命令行利用,GraalVM也有十分好的解决方案——Picocli + GraalVM Native Image + upx,它能够将Java利用编译为更便捷的可执行程序。

下图就是GraalVM多语言和Native Image反对列表,如下:

此外,各个云厂商也在踊跃JDK的开发,如AliJDK、Amazon Corretto、Azul等,这些都是对JDK倒退有十分好的作用。

所以说,对Spring而言,JDK这个根底还是十分巩固的。

二 充斥良性竞争的 JVM 语言

JDK并不是只能反对Java这一门编程语言,相同,它能够反对多种,比方Kotlin、Scala、Groovy等,这里咱们对立称之为JVM语言。当下,JVM语言正处于一个充斥良性的竞争状态。

咱们晓得每种语言都有本人善于的应用场景。在云原生时代,多语言开发反对十分重要,开发人员须要依据理论的业务场景抉择不同的开发语言。无论JVM语言或者GraalVM反对的语言,都能够和Spring间接整合,不便开发人员充分利用Spring技术栈做开发。

其中,对Spring反对最好的语言是Kotlin。Kotlin和Spring的整合曾经渗透到框架的各个方面,比方Spring Boot和Kotlin整合,Spring Webflux对Kotlin Coroutines & Flow的反对,Spring Data、SpringIntegration、SpringCloud Function等也都蕴含对Kotlin的反对,这些都实现了对Kotlin的深度整合,目标就是让语言和框架联合得更好,晋升开发效率。此外,Kotlin和Scala也是与Spring整合得比拟好的语言。

因为Java、Kotlin和Scala这三种语言在Spring中的整合十分好,所以接下来我就对它们具体阐明一下,帮忙你对JVM语言以后的倒退状况有一个比拟清晰的认知。

Java

Java语言的倒退还是十分疾速的,随同着OpenJDK的开发,Java半年就会推出一个版本,每个版本都会随同着语法的降级、规范库的降级等,极大中央便了开发人员。从Java 9到16,曾经实现了很多语法和个性方面的晋升,比方大家晓得var关键字(局部变量类型推导)、Text block、Pattern Matching for instanceof、Record、sealed interface等。

Kotlin

尽管说Kotlin不齐全是针对JVM的,它也包含Native、JavaScript等,然而Kotlin对JVM和Android的反对,目前是泛滥Kotlin平台中个性最多且稳固的。

当初Kotlin的发展势头十分迅速,曾经孵化了多个子项目,比方最新的Kotlin Multiplatform Mobile(一套代码反对多个手机平台)、 Kotlin Compose for Desktop(一套代码开发多操作系统的桌面端利用)等。当然,这些变动中最引入瞩目的是Kotlin 1.5推出的Kotlin intermediate representation (IR) ,借助于新的IR,Kotlin的代码能够编译输入到各种指标平台且程序更优,如大家都关注的Kotlin WebAssembly。

Scala

Scala 2是2006年3月公布的,距今曾经有十分长的工夫了。好的音讯是Scala 3.0曾经于2021年5月公布啦。Scala 3在增加新个性的同时,去除了Scala 2中一些艰涩的个性,目标是让Scala更好应用。如果你有趣味,能够关注下Scala3的官网。

Scala 3还有一个外围的变动是编译器的调整,名称为TASTy,是 Typed Abstract Syntax Trees的缩写,构造如下:

借助于TASTy,目前曾经有Scala.js ,后续有Scala WebAssembly也不奇怪。

Kotlin和Scala对函数编程都十分敌对,在这点上都补救了Java的有余。此外,Kotlin和Scala同时反对JavaScript编译输入,这个对基于V8的Serverless平台帮忙十分大,比方Cloudflare的Serverless平台。此外,Kotlin和Scala也在积极探索对WebAssembly反对,这些都是反对Web开发的好消息。

当然,JVM语言还有很多,如Groovy、Clojure等,也都在踊跃倒退,这些JVM语言彼此竞争,彼此借鉴,这对开发者来说,都是十分好的音讯。

Spring依赖的JDK和JVM语言说完了,上面咱们来聊聊Spring中十分胜利的两个我的项目SpringBoot 和 Spring Cloud。

Spring Boot和Spring Cloud是十分胜利的两个我的项目,基于Java技术栈的互联网公司根本都在应用。此外,近期如果你有关注Spring顶级布道师Josh Long的演讲的话,就会发现他始终在讲Spring Reactive,他还编写了一本书,就叫《Spring Reactive》。

那为什么Spring Boot、Spring Cloud和Spring Reactive会如此备受关注呢?

咱们晓得,对于云原生来讲,有两种十分重要的架构计划,一个是面向服务化架构,另一个是事件驱动架构。面向服务化架构通常基于同步的申请/响应模型,Spring Boot、Spring Cloud的指标就是反对这一个性;事件驱动架构则基于异步化的音讯模型和音讯路由,而Spring Reactive这个我的项目的外围就是撑持这一架构。

接下来,我就带你看看Spring具体是如何反对云原生里这两种重要的架构计划的,借此,你也会对Spring里重要的三个我的项目Spring Boot、Spring Cloud和Spring Reactive有一个比较清楚的认知。

三 成熟的面向服务架构的 Spring Boot 和 Spring Cloud

通常,云原生下的利用都偏向于微服务设计,而微服务设计的核心内容就是面向服务化架构设计和利用编程接口(API)治理,Spring Boot和Spring Cloud的指标就是反对这一个性的,而且这两个我的项目做得十分胜利,基于Java技术栈的互联网公司根本都在应用。

咱们晓得,服务化接口最典型的构造就是申请(Request)/响应(Response)模式,尤其是Web的Request/Response模式。当然了,近程RPC的request/response也在此领域,比方HTTP REST、gRPC和Dubbo。

对应到Spring中面向服务架构设计,SpringMVC能够十分好地反对Web和HTTP REST API,还包含对OpenAPI的反对。其余RPC类的通信,也都有对应的Spring Boot starter反对,在Spring Boot中也有对应的starter组件反对,开发也十分便捷。如果要裸露其余模式服务,如Web Service和SOAP等传统服务模式,也能够哦通过Spring Web Services(spring-ws)我的项目达成。

另一个个性API治理,次要波及服务治理和服务生产端调用,对应的核心技术栈次要是Spring Cloud我的项目。Spring Cloud为服务化架构和API治理提供了多种根底设置,如服务注册发现、负载平衡、API Gateway、断路爱护等,这些技术栈不便咱们更好地治理和治理服务,同时也让生产端能更好地调用服务。

综合下来,服务化架构和API治理,对应到Spring Boot和Spring Cloud技术栈,典型的架构如下:

如果你的架构是面向服务的,如波及到服务编排、服务治理和API Gateway等,那么Spring Cloud会是十分好的抉择,个性齐备、框架稳固、文档欠缺、历经过诸如阿里巴巴等亲自实际。如果你的公司基于Java技术栈,那么Spring Cloud是实现微服务架构最好的反对和实际。

阿里巴巴从2018年7月开始就开源了Spring Cloud Alibaba,截止至今,它曾经取得了超过1.9万的star数,曾经超过了所有其余实现的总和。从X-lab 凋谢实验室公布的《2020年微服务畛域开源数字化报告》中,咱们也看到Spring Cloud Alibaba曾经成为最沉闷、最受开发者欢送、工具链最欠缺的Spring Cloud实现。大家在选型过程中能够思考。

四 让事件驱动架构更易使用的 Spring Reactive

后面咱们讲述了Spring对面向服务架构的反对,还有另外一种架构模式,就是事件驱动架构。事件驱动架构被普遍认为是云原生首选的架构计划,那么Spring对这方面反对如何?这就波及到Spring Reactive这个我的项目了,其外围就是撑持事件驱动架构。

Spring Reactive是面向异步化音讯的,音讯或者事件是企业集成模式(EIP)首推的架构模式,你可能据说过Spring企业集成(SpringIntegration)这个我的项目,其次要就是负责企业集成。Spring Reactive的目标则是让事件驱动架构设计也能成为利用架构的首选,而且要更加简略。

这里讲一个题外话:我和一些资深的Spring Boot和Spring Cloud程序员交换过,大家对各种服务化接口设计一五一十,甚至包含代码层级的细节,然而一探讨到企业集成模式(EIP),都示意这是Martin Fowler的出名大做,问及大家的零碎中是否应用到诸如Apache Camel或者Spring Integration,大家都示意当初面向服务构造曾经满足业务需要啦。

那么这里就有一个问题,如此出名的EIP、ESB或者EDA为何没有在架构设计中所驳回?是灯下黑被忘记、还是门槛太高、或者压根就是一个纯理论,齐全脱离实际?

在面向服务化的架构设计中,根本都是基于服务接口调用,并且调用是同步的,所以服务编排、API治理起着十分重要的作用。当然在面向服务化的架构设计中,咱们也会引入一些音讯驱动设计,借助像Kafka或者其余MQ零碎,解决一些异步化或者数据分析的场景,如用户注册后发一封邮件、用户登录触发事件进行平安审计、商品信息或价格批改后触发搜索引擎增量索引、用户下单后触发各种告诉等等。

面向服务有其益处,然而要解决十分多的问题,如非阻塞、服务注册和发现、高性能、易集成等,这也是很多专家提出云原生场景中,事件驱动架构才是支流。

事件驱动架构不波及服务注册和发现这些负责的机制,基于音讯的路由也非常容易,异步化音讯通信的性能更高(当然你的账单也更小),各种SaaS服务集成也更简略(EventBridge产品)、FaaS触发容易等等。如果你想理解更多,能够看看《Building Event-Driven Microservices》这本书。这里贴一下Redhat举荐的基于微服务思维的事件驱动架构设计,如下:

从这张图中咱们能够看出,所有零碎之间的交互都是通过音讯进行通信的,微服务不再是面向接口的申请/响应设计,解决来自不同的利用的Request/Response申请,而是以一种异步化的形式一直地在解决来自Broker的音讯。

说到这里,你可能明确了,如果说Cloud Native以事件驱动设计架构为外围,那么Spring Reactive的目标是让事件驱动架构简略易用,开发便捷,这个就是Spring Boot和Cloud对面向服务架构的反对是一样的。此外这两种架构并不是矛盾的,都是能够互相共存和互相补充的。

要实现更好的事件驱动架构,两个根底少不了:异步化和音讯化。异步化能够解决线程期待的问题,而音讯及其音讯路由,能够很好地实现利用的松耦合。以后越来越多的产品应用异步化音讯计划,各种音讯产品中间件自不必说,大家熟知的HTTP/2都是基于异步音讯通信的。

那为何要异步化?咱们晓得音讯解决的模型和同步服务调用是不一样的,如音讯解决的Event Loop和Actor模型,都是十分高效的音讯解决形式,如果咱们在音讯解决的过程中,还要解决基于线程池的同步服务调用,势必会影响模型和性能。当然也不是齐全不能有同步,只是尽量避免过多的服务同步调用的场景。

围绕异步化和音讯的场景,Spring要做十分多的工作,咱们都晓得Java对异步化反对十分滞后。Java 1.8退出了CompletionStage接口,Java 9增加了Reactive Stream反对染指了Flow。大家始终关注的轻量级线程的Loom我的项目还在开发中,预计要到Java 17能力公布。

所以目前Java少数的我的项目我的项目都会抉择Reactive框架,当然Spring团队开发了Reactor框架,减少了Reactor对Netty、Kafka等适配,从而保障从底层开始就是异步化,所以这也是起名为Spring Reactive的起因。

接下来就是大家都看到的场景,Spring Webflux、Spring Integration、Spring Data等泛滥我的项目都增加了对异步化的反对,所有的这些调整,就是要确保从底层开始就是全异步化的,你能够了解为5G的非独立组网和独立组网两种形式,只是Spring抉择了Reactive这种独立组网、独立生态的形式,当然工作量也是十分大的。这其中就波及了两个十分大的问题:数据库和分布式通信。

目前大多数NoSQL产品都提供了异步化的接口,异步化拜访NoSQL产品没有什么问题。尽管NoSQL倒退很迅猛,然而还是没有撼动数据库的位置,咱们都晓得Java中数据库拜访的标准是JDBC,然而JDBC是同步的接口,所以Spring启动了R2DBC我的项目,目标就是可能以Reactive异步化接口拜访数据库,目前来说,在Spring框架下应用JDBC和R2DBC的体验简直是统一的。

这里我和同学们同步两个音讯:Spring 5.3曾经内置R2DBC反对,也就是spring-r2dbc,和spring-jdbc并列。大家都喜爱应用的MySQL数据库,也推出了mariadb-r2dbc 1.0.0稳定版,Oracle也推出了R2DBC版本的驱动。当然Java中的DB框架,Spring JPA、MyBatis等都增加了对R2DBC的适配。Hibernate也推出了hibernate-reactive我的项目(基于Vert.x database),尽管是不是基于R2DBC的,然而也是全异步化的。

另外一个问题就是分布式通信,这个在微服务架构中表演中十分重要的作用。始终以来Spring次要反对HTTP,然而HTTP协定次要是针对浏览器设计的,在后端服务之间通信劣势并不显著,而且性能上也没有劣势。当然基于HTTP/2异步音讯通信的gRPC是一个很好的抉择,然而Spring始终没有内置gRPC反对,当然这对大多数开发者来说,这不是什么大问题,第三方的grpc-spring-boot-starter做的也十分好。

如果你关注Spring公布的话应该晓得,Spring 5.2后续版本抉择RSocket通信协定,并将RSocket内置到spring-message我的项目中。为何?RSocket是全异步的二进制音讯通信协定,提供了齐备的通信模型,而且是对等通信的,十分匹配事件驱动架构,这也是Spring Reactive将RSocket纳入到Spring外围的起因,当然RSocket背地的开发,Spring和阿里团队起着主导作用。

CNCF下有一个CloudEvents标准,次要解决异构零碎的事件通信,音讯和事件在数据结构上是统一的,都是Headers和Payload(data)构造,同时蕴含音讯头的扩大。最新的cloudevents-java SDK 2.1,Spring messaging增加了对CloudEvents的反对,同时反对CloudEvent接口的编解码反对,将音讯和事件进行了对立和整合,在Spring中解决CloudEvents和音讯更简略。

和企业集成相干产品,如Apache Camel, 基于Akka的Alpakk、MuleSoft的Mule 4、Spring Integration等,这些产品都提供了对Reactive的集成,能够说能够和Spring Reactive无缝对接。

五 总结

回到文章的问题,为什么Spring 依然会是云原生时代最佳平台之一?总结下来,Java和JDK的开发处以十分好的倒退,JVM语言良性倒退且充斥竞争。成熟的Spring Boot和Spring Cloud曾经让面向服务的架构设计简略易用,而Spring Reactive则将事件驱动架构更易被应用,同时能够让更多的企业零碎实现和Spring Reacitve对接,无论是IoT设施、ESB产品、SaaS或者云服务等。

针对微服务的场景,Spring Cloud提供了成熟的面向架构服务根底,Spring Reactive则是面向未来的事件驱动架构,当然这里并不是说,面向服务的架构曾经过期,事实上面向服务的架构十分胜利,然而在云原生或新的Serverless环境下,可能事件驱动架构可能更正当一些,或者是两者的配合应用,不必放心,Spring在这两方面都做的十分好。

原文链接
本文为阿里云原创内容,未经容许不得转载。