接上一篇:java
实战SpringCloud响应式微服务系列教程(第一章)react
实战SpringCloud响应式微服务系列教程(第二章)
编程
响应式编程是一种编程模型,本节将介绍这种编程模型的具体实现工具 Project Reactor框架。 Reactor框架也是 Spring5中实现响应式编程采用的默认框架。bash
Project Reactor: https://projectreactor.io/网络
响应式编程就是利用异步数据流进行编程,本质上就是观察者( Observer)模式的一种表现形式。本节首先讨论实现异步操做的几种常见方式,而后引出响应式编程的主流实现技术。架构
1.实现异步操做的常见方式并发
在Java中,为了实现异步非阻塞,通常会采用回调( Callback)和 Future这两种机制,但这两种机制都存在必定局限性。框架
(1)回调异步
回调的含义如图所示,即类A的 method A()方法调用类B的 method B()方法,而后类B的 methodB()方法执行完毕后再主动调用类A的 callback()方法。回调体现的是一种双向的调用方式。分布式
能够看到,回调在任务执行过程当中不会形成任何阻塞,任务结果一且就绪,回调就会被执行。但咱们也应该看到在使用回调机制时,代码会从一个类中的某个方法跳到另外一个类中的某个方法,从而形成流程的不连续性。对于单层的异步执行而言,回调很容易使用。
可是对于嵌套的多层异步组合而言,就显得很是笨拙。因此回调很难大规模地组合起来使用,由于很快就会致使代码难以理解和维护,即造成所谓的“回调地狱( Callback Hell)”问题。
(2) Future
能够把 Future模式简单理解为这样一种场景:有一个但愿处理的任务,把这个任务提交到 Future, Future就会在必定时间内完成这个任务,而在这段时间内咱们能够去作其余事情。
做为 Future模式的实现,Java中的 Future接口只包含以下5个方法
public interface Puture<v>{
boolean cancel (boolean mayinterrupt Ifrunning):
boolean iscancelled
boolean isdone ():
V get() throws Interruptedexception, Executionexception;
V get (long timeout, Timeunit unit)?
throws Interruptedexception, Executionexception, Timeoutexception
}复制代码
Future接口中的 cancel方法用于取消任务的执行; iscancelledo方法用于判断任务是否已经取消;两个get()方法会等待任务执行结束并获取结果,区别在因而否能够设置超时时间,最后 isDone()方法判断任务是否已经完成。
Future虽然能够实现获取异步执行结果的需求,可是它没有提供通知机制,咱们没法得知 Future何时完成。为了获取结果,咱们要么使用阻塞的两种get()方法等待 Future结果的返回,这时至关于执行同步操做;
要么使用 isDone方法轮询地判断 Future是否完成,这样会耗费CPU资源。因此, Future适合单层的简单调用,对于嵌套的异步调用而言一样很是笨重,不适合复杂的服务链路构建。
鉴于Future机制存在的缺陷,Java8中引入了 Completablefuture 机制。 Completablefuture在必定程度上弥补了普通 Future的缺点。在异步任务完成后,咱们使用任务结果时就不须要等待,能够直接经过 thenaccept()、 thenApply()、 thencompose()等方法将前面异步处理的结果交给另一个异步事件处理线程来处理。
Completablefuture提供了很是强大的 Future扩展功能,能够帮助咱们简化异步编程的复杂性,而且提供了函数式编程的能力,能够经过回调的方式处理计算结果,也支持转换和组合 Completablefuture所提供的各类方法。
对平常开发工做而言,大多数时候咱们是在处理简单的任务,这时使用 Completablefuture确实能够知足需求。可是,当系统愈来愈复杂,或者咱们须要处理的任务自己就很是复杂时,Completablefuture对于多个处理过程的组合仍然不够便捷。使用 Completablefuture编排多个Future是可行的,但并不容易。咱们会担忧写出来的代码是否真的没有问题,而随着时间的推移,这些代码会变得愈来愈复杂和难以维护。为此,咱们须要引入响应式编程的相关技术和框架,这些技术和框架可以支持将来更轻松地维护异步处理代码。
2.响应式编程的主流实现技术
目前,响应式编程的主流实现技术包括 Rxjava、 Akka Streams、Vert.x和 Project Reactor等。
(1)Rxjava
Reactive Extensions(Rx)是一个类库,它集成了异步基于可观察( Observable)序列的事件驱动编程,最先应用于微软的NET平台。而 Rxjava是 Reactive Extensions 的Java实现用于经过使用 Observable/ Flowable序列来构建异步和基于事件的程序库,目前有1x版本和2.x版本两套实现。
Rxjava1.x誕生于响应式流规范以前,虽然能够和响应式流的接口进行转换,可是因为底层实现的缘由,使用起来并非很直观。 Rxjava2在设计和实现时考虑到了与现有规范的整合,按照响应式流规范对接口进行了重写,并把1.x版本中的背压功能单独分离出来。但为了保持与 Rxjava1x的兼容性, Rxjava2在不少地方的使用也并不直观。关于 Rxjava的更多内容,可参考官网(http://reactivex.io/),咱们这里不作过多介绍。
(2)Akka Streams
Akka运行在JVM上,是构建高并发、分布式和高弹性的消息驱动应用程序的一个工具件。 Actor是Akka中最核心的概念,它是一个封装了状态和行为的对象,Actor之间能够经过交换消息的方式进行通讯。经过 Actor可以简化锁及线程管理,能够很是容易地开发出正确的并发程序和并行系统。
Akka也是响应式流规范的初始成员,而 Akka Streams是以Aka为基础的响应式流的实现,在Akka现有的角色模型之上提供了一种更高层级的抽象,支持背压等响应式机制。
(3) Vertx
Vert. x是 Eclipse基金会下的一个开源的Java工具,是一个异步网络应用开发框架,用来构建高并发、异步、可伸缩、多语言支持的Web应用程序。Vert.x就是为了构建响应式系统而设计的,基于事件驱动架构, Vert x实现了非阻塞的任务处理机制。
verx中包含Vert.x Reactive Streams工具库,该工具库提供了Vver.x上响应式流规范的实现。咱们能够经过 Vert x提供的可读流和可写流处理响应式流规范中的发布者和订阅者。
(4) Project Reactor
Spring S中引入了响应式编程机制,而 Spring5中默认集成了 Project Reactor做为该机制的实现框架。 Reactor诞生较晚,能够认为是第二代响应式开发框架。
因此,它是一款彻底基于响应式流规范设计和实现的工具库,没有 Rxjava那样的历史包,在使用上更加直观、易懂。但从设计理念和API的表现形式上, Reactor与 Rxjava比较相似,能够说 Reactor基于响应式流规范,但在API方面又尽量向 Rxjava靠拢。
Flux和Mono是 Reactor中的两个核心组件,Flux表明包含0到n个元素的异步序列,而Mono则表示0个或者一个元素的序列。Reactor框架使咱们讨论的重点,下一节咱们将从Reactor框架的引入具体讲解Flux和Mono。