响应式编程到底是什么?

2022-12-06 0 753

作者:昌明评析Broadview

出自于:InfoQ 诗歌创作网络平台

书名:xie.infoq.cn/article/277867e2d5af56de29c6031a6

最近几年,随着Go、Node 等新词汇、新技术的再次出现,Java 做为服务端合作开发词汇大哥的话语权受到了非常大的考验。尽管Java 的市场话语权在短时期内并不会发生改变,但Java 街道社区还是将考验视作发展机遇,并努力、不断地提高自身应付高mammalian服务端合作开发场景的能力。

为了应付高mammalian服务端合作开发情景,在2009 年,谷歌提出了一个更典雅地与此同时实现触发器程式结构设计的形式——Reactive Programming,他们称作积极响应式程式结构设计。随后,各词汇很快介入,都拥有了属于自己的积极响应式程式结构设计与此同时实现。比如说,JavaScript 词汇就在ES6 中透过Promise 机制导入了类似的触发器程式结构设计形式。与此同时,Java 街道社区也在快速发展,Netflix 和LightBend 子公司提供更多了RxJava 和Akka Stream 等控制技术,使得Java 网络平台也有了能够与此同时实现积极响应式程式结构设计的架构。

当今社会,他们透过Mina 和Netty 这种的NIO 架构只不过就能完成高mammalian下的服务端合作开发各项任务,但这种的控制技术只掌握在少数高级合作开发人员手中,因为它们技术难度较大,并不适宜大部分普通合作开发人员。

尽管目前已经有不少子公司在课堂教学积极响应式程式结构设计,但整体而言,其应用范围依旧不大。再次出现这种情况的原因是当今社会缺乏简单、功能强大的控制技术,这些控制技术需要能使积极响应式程式结构设计更加普及化,并努力做到有如Spring MVC 一样结合Spring 提供更多的服务对各种控制技术展开资源整合。

在2017 年9 月28 日,Spring 5 正式正式发布。Spring 5 正式发布最大的意义是,它将积极响应式程式结构设计控制技术的普及化向前推进了大步。而与此同时,做为在背后支持Spring 5 积极响应式程式结构设计的架构Spring Reactor,也进入了划时代的3.1.0 版。

积极响应式程式结构设计究竟是甚么?在现实中,当他们听到有人喊他们名字的时候,会对其展开积极响应,也是说,他们是基于该设计模式模式来展开程式结构设计的。所以那个过程只不过是印发产生的该事件,接着他们做为顾客对印发该事件展开一系列的消费。

从那个角度而言,对整个标识符的结构设计应该是针对顾客来展开的。比如说,看影片,很多镜头他们不该看,那就站著;很多声音不该听,那就捂上嘴巴。只不过这是对顾客的增强包装袋,他们把复杂的方法论拆合二为一,接着将其拆分成一个个小各项任务展开PCB,于是就有了譬如filter、map、skip、limit 等操作。两本书会用大量的字数来阐释源标识符结构设计方法论。

mammalian与博戈达的关系

可以说,mammalian很好地利用了CPU 时间片的特性,也是操作系统选择并运行一个各项任务,接着在下一个时间片内运行另一个各项任务,并把前一个各项任务设置成等待状态。只不过mammalian并不意味着博戈达。

具体列举下面几种情况。

有时候,多线程执行会提高应用程序的性能,而有时候反而会降低应用程序的性能。这在 JDK 中Stream API 的使用上体现得很明显,如果各项任务量很小,而他们又使用了博戈达流,反而降低了应用程序的性能。在多线程程式结构设计中,可能会与此同时开启或者关闭多个线程,这种会产生很大的性能开销, 也降低了应用程序的性能。当线程与此同时处于等待I/O 的过程中时,mammalian可能会阻塞CPU 资源,其后果不仅是用户长时间等待,而且会浪费CPU 的计算资源。如果几个线程共享了一个数据,情况就会变得很多复杂。他们需要考虑数据在各个线程中的状态是否一致。为了达到数据一致的目的,很可能会使用synchronized 或者lock 相关操作。

现在,你对mammalian有一定的了解了吧。mammalian很好,但并不一定会与此同时实现博戈达。博戈达是在多核CPU 上同一时间运行多个各项任务或者一个各项任务分为多块与此同时执行(如ForkJoin)。单核CPU 的话,就不要考虑博戈达了。

补充一点,实际上多线程就意味着mammalian,但是博戈达只发生在这些线程在同一时间调度、分配到不同CPU 上执行的情况下。也是说,博戈达是mammalian的一种特定形式。一个各项任务里往往会产生很多元素,这些元素在不参与操作的情况下大都只能处于当前线程中,这时他们可以对其展开ForkJoin,但这对很多程序员来讲有时候很不好操作、控制,上手技术难度很多大。这时如果用积极响应式程式结构设计,就可以简单地透过所提供更多的调度API 轻松努力做到该事件元素的印发、分配,其内部会将每个元素包装袋成一个各项任务并提交到线程池中,他们可以根据各项任务是计算型的还是I/O 型的来选择相应的线程池。

在这里,需要强调一下,线程只是一个对象,不要把它想象成CPU 中的某一个执行核心,这是很多人都在犯的错,CPU 时间片会切换执行这些线程。

如何理解积极响应式程式结构设计中的背压

背压,由Back Pressure 翻译得到,从英文字面意思讲,称作回压可能更合适。首先解释一下回压,它就好比用吸管喝饮料,将吸管内的气体吸掉,吸管内形成低压,进而形成饮料至吸管方向的吸力,此吸力将饮料吸进人嘴里。他们常说人往高处走,水往低处流,水之所以会再次出现这种现象,只不过是重力所致。而现在吸管下方的水上升进入人的口中,说明再次出现了下游指向上游的逆向压力,而且那个逆向压力大于重力,可以称这种情况为背压。这是一个很直观的词,向后的、往回的压力——Back Pressure。

放在程序中,也是在数据流从上游源生产者向下游顾客传输的过程中,若上游源生产速度大于下游顾客消费速度,那么可以将下游想象成一个容器,它处理不了这些数据,接着数据就会从容器中溢出,也就再次出现了类似于吸管例子中的情况。现在,他们要做的事情是为那个情景提供更多解决方案,该解决方案被称为背压机制。

为了更好地解决背压带来的问题,他们回到现实中看一个事物——大坝。在发洪水期间,下游没办法一下子消耗那么多水,大坝此时的作用是拦截洪水,并根据下游的消耗情况酌情排放,也是说,背压机制应该放在连接元素生产者和顾客的地方,即它是生产者和顾客的衔接者。接着,根据上面对大坝的描述,背压机制应该具有承载元素的能力,也是它必须是一个容器,而且其存储与印发的元素应该有先后顺序,那么这里使用队列是最适宜的了。背压机制仅起承载作用是不够的,正因为上游展开了承压,所以下游可以按需请求元素,也可以在中间根据实际情况展开限流,以此上下游共同与此同时实现了背压机制。在两本书后续内容及相关的配套视频中会介绍背压的相关API。

Reactor 与RxJava 的对比

关于积极响应式程式结构设计,Reactor 与RxJava 又有甚么区别呢?首先我要明确地告诉你,如果你使用的是Java 8+,那么推荐使用Reactor 3,而如果你使用的还是Java 6+或函数需要做异常检查,那么推荐使用RxJava 2。

下面来看图1-1。

响应式编程到底是什么?

从图1-1 可以看到,RxJava 2 和Reactor 共用了一套接口API 标准Reactive Streams Commons,这也说明它们的最终目的是一致的,而且API 具有通用性,这种也降低了学习成本。

下面再来回顾一下RxJava。迄今为止,RxJava 发行版主要分三大版RxJava 3、RxJava 2 和RxJava 1。与RxJava 1 不同,RxJava 3、RxJava 2 直接透过新添加的Flowable 类型来与此同时实现Publisher 的接口定义(RxJava 3 与RxJava 2 并没有太多区别,故这里只介绍RxJava 2)。与此同时,RxJava 2 依然保留了RxJava 1 中的Observable、Completable 和Single,并导入了支持Optional 的Single 升级版——Maybe 类型。RxJava 1 中的Observable 不支持RxJava 2 中的背压机制,背压机制是Flowable 的专有功能,不过Observable 内部提供更多了可转换API。需要注意的是,Observable 与此同时实现的是RxJava 2 中自定义的ObservableSource 接口。

在Reactor 中,可以发现Mono 和Flux 两种类型都与此同时实现了Publisher 接口,与此同时两者皆与此同时实现了背压机制。Flux 可以对标RxJava 2 中的Flowable 类型,而Mono 可以被理解为RxJava 2 中对Single 的背压加强版。后续,他们会展开更深入的讲解。

同样,下面再来了解一下Reactor 与RxJava 的不同之处。

为了兼容 Java 1.6+ ,RxJava 不得不自行定义了一些函数式接口,可以参考io.reactivex.functions 下的接口定义。而Reactor 3 则是基于JDK 中提供更多的java.util.function 来结构设计与此同时实现的。可以很轻松地从java.util.stream.Stream 转换为Flux,也可以很轻松地由后者转换为前者。同样,可以很轻松地与此同时实现CompletableFuture 与Mono 之间的互相转换,也可以轻松而安全地基于Optional 类型的元素创建Mono。从图 1-1 中还可以看到,Reactor 3 可以更好地服务于Spring Framework 5,也更适应最新版的JDK。

最后,简单介绍一下图1-1 中的几个部分。

Core:是他们主要研究的库,是Reactor 的核心与此同时实现库。其作用与RxJava 2 的核心与此同时实现的作用是一样的,两本书主要介绍reactor-core 模块。IPC:可以认为它是针对encode、decode、send(unicast、multicast 或request/response)及服务连接而结构设计的支持背压的组件。IPC 支持Kafka、Netty 及Aeron。Addons:其中包括reactor-adapter、reactor-logback 和reactor-extra。reactor-adapter 可以说是连接RxJava 1/2 中Observable、Completable、Flowable、Single、Maybe、Scheduler 的桥梁,可以方便地与Reactor 3 展开转换操作。同样,那个库对于Swing/SWT Scheduler、Akka Scheduler 也做了针对性适配。reactor-logback 用于支持Reactor Core 触发器处理Logback 方面的功能。reactor-extra 为数字类型的Flux 源提供更多了很多数学运算的操作。Reactive Streams Commons:是RxJava 2 和Reactor 共用的一套接口API 标准。

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务

BP宝库站

Hi,欢迎来到BP宝库,需要外包可联系qq:2405474279 WordPress、网站、SEO优化、小程序、爬虫、搭建外包服务应有尽有

我知道了