响应式编程系列一《规约》

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/itsoftchenfei/article/details/83089051

提升开发效率,降低维护成本一直是开发团队永恒不变的宗旨。近两年来国内的技术圈子中越来越多的开始提及ReactiveX,越来越多的应用和面试中都会有ReactiveX,响应式编程中RxJava可谓如鱼得水。

目录

1. 背景

2. 响应式编程是什么

3. 优势 & 代价

4. Reactive Streams规约

4.1 Publisher

4.2 Subscriber

4.3 Subscription

4.4 Processor

5. 主流实现

5.1 Rx2.x

5.2 Reactive Stream

5.3 Java9

5.4 Spring WebFlux

5.5 Vertx


1. 背景

前面提到过是为了提升开发效率,降低维护成本。

2. 响应式编程是什么

响应式编程是一种基于异步数据流概念的编程模式。数据流就像一条河:它可以被观测,被过滤,被操作,或者为新的消费者与另外一条流合并为一条新的流。响应式编程的一个关键概念是事件。事件可以被等待,可以触发过程,也可以触发其它事件。

Rx提供了一系列的操作符,你可以使用它们来过滤(filter)、选择(select)、变换(transform)、结合(combine)和组合(compose)多个Observable,这些操作符让执行和复合变得非常高效。

响应式流从2013年开始,作为提供非阻塞背压的异步流处理标准的倡议。它旨在解决处理元素流的问题——如何将元素流从发布者传递到订阅者,而不需要发布者阻塞,或订阅者有无限制的缓冲区或丢弃。

 响应式流模型非常简单——订阅者向发布者发送多个元素的异步请求。 发布者向订阅者异步发送多个或稍少的元素。响应式流在pull模型和push模型流处理机制之间动态切换。 当订阅者较慢时,它使用pull模型,当订阅者更快时使用push模型。

 在2015年,出版了用于处理响应式流的规范和Java API。请访问http://www.reactive-streams.org/

3. 优势 & 代价

优势

  • 函数式风格:对可观察数据流使用无副作用的输入输出函数,避免了程序里错综复杂的状态;
  • 简化代码:Rx的操作符通通常可以将复杂的难题简化为很少的几行代码(声明式的组合这些序列);
  • 异步错误处理:传统的try/catch没办法处理异步计算,Rx提供了合适的错误处理机制;
  • 轻松使用并发:Rx的Observables和Schedulers让开发者可以摆脱底层的线程同步和各种并发问题;

代价

  1. 虽然复用线程有助于提高吞吐量,但一旦在某个回调函数中线程被卡住,那么这个线程上所有的请求都会被阻塞,最严重的情况,整个应用会被拖垮。
  2. 难以调试。由于 Rx 强大的描述能力,在一个典型的 Rx 应用中,大部分代码都是以链式表达式的形式出现,比如flux.map(String::toUpperCase).doOnNext(s -> LOG.info("UC String {}", s)).next().subscribe(),一旦出错,你将很难定位到具体是哪个环节出了问题。所幸的是,Rx 框架一般都会提供一些工具方法来辅助进行调试。

4. Reactive Streams规约

4.1 Publisher

是潜在无限数量的有序元素的生产者。 它根据收到的要求向当前订阅者发布(或发送)元素

4.2 Subscriber

从发布者那里订阅并接收元素。 发布者向订阅者发送订阅令牌(subscription token)。 使用订阅令牌,订阅者从发布者哪里请求多个元素。 当元素准备就绪时,发布者向订阅者发送多个或更少的元素。 订阅者可以请求更多的元素。 发布者可能有多个来自订阅者的元素待处理请求。

4.3 Subscription

表示订阅者订阅的一个发布者的令牌。 当订阅请求成功时,发布者将其传递给订阅者。 订阅者使用订阅令牌与发布者进行交互,例如请求更多的元素或取消订阅。

4.4 Processor

充当订阅者和发布者的处理阶段。Processor<T,R>订阅类型T的数据元素,接收并转换为类型R的数据,并发布变换后的数据,该接口继承了PublisherSubscriber接口。

5. 主流实现

5.1 Rx2.x

RxJava是响应式流的Java实现之一,而RxJava 2.0 已经按照Reactive-Streams specification规范完全的重写了。

5.2 Reactive Stream

Reactor 2.0.0.RC1 于2015年02月19日由Pivotal RTI(Spring 框架发起者)发布,支持 Reactive Stream,它的构架总览:

注:上图参考附录Reactor指南中文版,Reactor1.x实在是不太出名,也是规范没出来吧

Reactor 代码库拆分成多个子模块,便于选择所需功能,不受其他功能代码块干扰。

下面举例说明,为实现异步目标,响应式技术和 Reactor 模块该如何搭配:

  1. Spring XD + Reactor-Net (Core/Stream): 使用 Reactor 作为 Sink/Source IO 驱动。
  2. Grails | Spring + Reactor-Stream (Core): 用 Stream 和 Promise 做后台处理。
  3. Spring Data + Reactor-Bus (Core): 发射数据库事件 (保存/删除/…​)。
  4. Spring Integration Java DSL + Reactor Stream (Core): Spring 集成的微批量信息通道。
  5. RxJavaReactiveStreams + RxJava + Reactor-Core: 融合富结构与高效异步 IO 处理
  6. RxJavaReactiveStreams + RxJava + Reactor-Net (Core/Stream): 用 RxJava 做数据输入,异步 IO 驱动做传输。

与Rx2.x的差异

RxJava

reactor-stream

说明

Observable

reactor.rx.Stream

Reactive Stream Publisher的实现

Operator

reactor.rx.action.Action

Reactive Stream Processor的实现

Observable with 1 data at most

reactor.rx.Promise

返回唯一结果的类型,  Reactive Stream Processor实现并提供了可选的异步分发功能。 

Factory API (just, from…)

reactor.rx.Streams

和core模块的 data-focused 子类一样, 返回 Stream

Functional API (map, filter…)

reactor.rx.Stream

和core模块的data-focused 子类一样, 返回Stream

Schedulers

reactor.core.Dispatcher, org.reactivestreams.Processor

Reactor Stream计算无限制的共享Dispatcher或者有限的Processor的操作。

Observable.observeOn()

Stream.dispatchOn()

只是dispatcher参数的一个适配命名。

5.3 Java9

JDK 9 java.util.concurrent 包提供了两个主要的 API 来处理响应流:

  1. Flow
  2. SubmissionPublisher

5.4 Spring WebFlux

Spring WebFlux 是 Spring 5 的一个新模块,包含了响应式 HTTP 和 WebSocket 的支持,在容器中 Spring WebFlux 会将输入流适配成 Mono 或者 Flux 格式进行统一处理。,另外在上层服务端支持两种不同的编程模型:
- 基于 Spring MVC 注解 @Controller 等
- 基于 Functional 函数式路由

为啥只能运行在 Servlet 3.1+ 容器?3.1 规范其中一个新特性是异步处理支持。

5.5 Vertx

Vert.x是一个异步无阻塞的网络框架,其参照物是node.js。基本上node.js能干的事情,Vert.x都能干。Vert.x利用Netty4的EventLoop来做单线程的事件循环,所以跑在Vert.x上的业务不能做CPU密集型的运算,这样会导致整个线程被阻塞。

Vert.x目前是见过功能最强大(core、web、Data access、reacive、microservices、MQTT,第三方库依赖最少的Java框架,它只依赖Netty4以及Jacskon,另外如果你需要建立分布式的Vert.x则再依赖HazelCast这个分布式框架,注意Vert.x3必须基于Java8。

总结,响应式编程已经慢慢成我我们开发中的主流,后续将带您深入了解《rxjava

猜你喜欢

转载自blog.csdn.net/itsoftchenfei/article/details/83089051