赠书:响应式编程到底是什么?

2022-12-06 0 300

点选下方红色“流程猿DD”,选择“标为隆哥蒙”

资源

赠书:响应式编程到底是什么?

前段时间一两年,随着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 版。

积极响应式程式设计究竟是甚么?在现实中,当他们听见有人喊他们英文名字的时候,会对其展开积极响应,换句话说,我们是如前所述该设计商业模式商业模式来展开程式设计的。所以这个过程只不过就是印发产生的该事件,然后他们做为顾客对印发该事件展开一连串的消费。

从这个角度来说,对整个代码的设计应该是针对顾客来展开的。比如说,看电影,有些画面他们不想看,那就闭上眼睛;有些声音不想听,那就捂上耳朵。只不过这就是对顾客的增强包装,他们把复杂的逻辑拆分开,然后将其分割成一个个小任务展开封装,于是就有了诸如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 的对比

关于积极响应式程式设计,我写的《Java 程式设计方法论:积极响应式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 类型(这点在《Java 程式设计方法论:积极响应式RxJava 与代码设计实战》一书中并没有提及,此处只是说明一下,并不会深究)。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 标准。

本文节选自《Java程式设计方法论:积极响应式Spring Reactor 3设计与与此同时实现》一书

知秋 著 电子工业出版社出版

知秋

本名李飞飞,simviso团队创始人,曾长期致力于基础代码库研发工作,对JDK、Spring、RxJava、Spring Reactor、Netty、Reactor-Netty、RSocket等有深刻的研究和独到的见解,并以此打造“Java程式设计方法论系列丛书”。一直透过博客与视频网络平台bilibili(B站),紧密结合自己的经验展开大量源码解读分享。现在主要致力于带领simviso的小伙伴引进、翻译国外知名高校计算机科学相关课程及国外知名Java合作开发人员的控制技术分享内容。

一九六九年活动

截止时间:2020年11月1日 11:30

如何抽奖抽奖1027 

赠书:响应式编程到底是什么?

往期推荐

一款 Java 开源的 Spring Boot 即时通讯 IM 聊天系统

Docker 入门终极指南:边学边用

推荐一款日志切割神器

成为最差合作开发人员的10条建议

delete、truncate、drop的区别有哪些,该如何选择

为何从单体架构迁移到微服务这么难?

扫一扫,关注我

一起学习,一起进步

每周一九六九年,福利不断

赠书:响应式编程到底是什么?

深度内容

推荐加入

赠书:响应式编程到底是什么?

前段时间热门内容回顾   #控制技术人系列

赠书:响应式编程到底是什么?

相关文章

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

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