接着之前的:
实战 SpringCloud 响应式微服务系列教程(第一章)
实战 SpringCloud 响应式微服务系列教程(第二章)
1.1.3Reactor 框架
响应式编程是一种编程模型, 本节将介绍这种编程模型的具体实现工具 Project Reactor 框架. Reactor 框架也是 Spring5 中实现响应式编程采用的默认框架.
Project Reactor: https://projectreactor.io/
1.1.4 响应式编程实现技术概述
响应式编程就是利用异步数据流进行编程, 本质上就是观察者 ( 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.
来源: https://www.cnblogs.com/javazhiyin/p/11410837.html