乐趣区

关于serverless:为什么Spring仍然会是云原生时代最佳平台之一

简介:基于 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 在这两方面都做的十分好。

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

退出移动版