浅谈响应式编程

Posted 白杨学论号

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈响应式编程相关的知识,希望对你有一定的参考价值。

本篇文章来源于我今天的学习成果,所以只能算是浅显而谈。

响应式编程(Reactive Programming),由于不是从事软件架构师工作,我第一次看到这个名词,其实是在Spring5发布时的一个Reactive Spring的概念。按照下图左边来看,其地位相对重要,而我却还一无所知。

浅谈响应式编程

关注IT程序或架构技术的人今年来肯定看到许多关于函数式编程和响应式编程的文章,其实这些概念早在上个世纪末就存在,类似于我们大学时期学习的面向对象编程,是编程理念和设计思想的基础。响应式编程这两年在程序界热度很高,支持者提出了种种优点,由于我自己没有做个类似项目,所以这方面不做评价。关于响应式编程相关技术,涉及内容实在广泛,我也是很少量的时间基于兴趣的了解了一下,下面分享一些学习成果,便于初学者入门。我会分步简单描述一下其核心思想。


首先,先看什么叫做响应,Reactive。

比如下面伪代码的例子:

a=1

b=a+1

print(b) //输出显示 2

a=10

print(b) //输出依旧显示 2

c <= a+1  //变量间建立一种关系

print(c) //输出显示11

a = 20

print(c) //输出显示为 21

上面示例是伪代码,核心是a 与 b是传统的变量赋值关系,而a与c是构建了一种依赖的关系,如果a变化,c会自动变化。这种依赖是构成响应式的基础。excel的公式功能是响应式的一个典范,经过公式计算的单元格,会随着公式内其他单元格变量的变化,自动变化。


再有,我们来看一下异步非阻塞响应。

https://www.zhihu.com/question/19732473/answer/23434554

例子如下:

老张爱喝茶,废话不说,煮开水。
出场人物:老张,水壶两把(普通水壶,简称水壶;会响的水壶,简称响水壶)。
1 老张把水壶放到火上,立等水开。(同步阻塞)
老张觉得自己有点傻
2 老张把水壶放到火上,去客厅看电视,时不时去厨房看看水开没有。(同步非阻塞)
老张还是觉得自己有点傻,于是变高端了,买了把会响笛的那种水壶。水开之后,能大声发出嘀~~~~的噪音。
3 老张把响水壶放到火上,立等水开。(异步阻塞)
老张觉得这样傻等意义不大
4 老张把响水壶放到火上,去客厅看电视,水壶响之前不再去看它了,响了再去拿壶。(异步非阻塞)
老张觉得自己聪明了。

所谓同步异步,只是对于水壶而言。
普通水壶,同步;响水壶,异步。
虽然都能干活,但响水壶可以在自己完工之后,提示老张水开了。这是普通水壶所不能及的。
同步只能让调用者去轮询自己(情况2中),造成老张效率的低下。

所谓阻塞非阻塞,仅仅对于老张而言。
立等的老张,阻塞;看电视的老张,非阻塞。
情况1和情况3中老张就是阻塞的,媳妇喊他都不知道。虽然3中响水壶是异步的,可对于立等的老张没有太大的意义。所以一般异步是配合非阻塞使用的,这样才能发挥异步的效用。


响应式编程的概念

前面谈到了响应,异步,非阻塞的概念,其实感觉很好理解吧。编程模型都是真实世界还原抽象提炼的。以下一段内容来自wiki百科:

In computing, reactive programming is a declarative programming paradigm concerned with data streams and the propagation of change. With this paradigm it is possible to express static (e.g., arrays) or dynamic (e.g., event emitters) data streams with ease, and also communicate that an inferred dependency within the associated execution model exists, which facilitates the automatic propagation of the changed data flow.[citation needed]


第一句话中的核心讲了两件事,数据流(data streams)和传播变化(propagation of change),同时提出声明式编程(declarative programming)。根据我上文写道的栗子,关于这两个概念,可以这样解释:传播变化,比如水壶响了告诉老张,那么这里的数据流就是水壶的响声,通过空气传播给老张的耳朵。声明式,类似我前面代码里a,b,c的栗子,c就是在生命它与a的关系是+1的,这就是声明式。其实这就是响应式编程的核心概念,非常容易理解,和很多C/S程序员在做listener,响应用户键盘鼠标状态感觉类似。


响应式流

首先想象一下这样的一个数据流,假设有a,b,c,x,y,z,x=f1(a,b),y=f2(b,c),z=f3(x,y)。abc是变量,xy是中间值,z是最终值,在真实程序开发的业务场景也可能如此,如果f1,f2,f3三个函数既定好,a,b,c其中一个变化,z则可能产生变化。对于复杂系统外部来看,输入和输出不同,其内部每个环节就是通过数据流传递的,而传递的过程中要符合响应式的概念。关于响应式流(Reactive Streams)。

http://www.reactive-streams.org/ 给出这样的描述:

Reactive Streams is an initiative to provide a standard for asynchronous stream processing with non-blocking back pressure. This encompasses efforts aimed at runtime environments (JVM and javascript) as well as network protocols.

NEWS: JDK9 java.util.concurrent.Flow

等一下,JDK9。我上网查了一下,JDK已经发布到12版本了(我上次写Java Web,当时还在用JDK8浅谈响应式编程)。

浅谈响应式编程

今天先不研究JDK,继续说响应式流。上文描述,响应式流,是提出了一种异步非阻塞回压的流处理的标准,包括运行时环境(JVM和JavaScript)及网络协议。

a.先解释一下这里的网络协议:

Network Protocols

This working group defines network protocols for passing reactive streams over various transport media that involve serialization and deserialization of the data elements. Examples of such transports are TCP, UDP, HTTP and WebSockets.

是为了定义在传统TCP、UDP、HTTP及WebSockets上,序列化或非序列化的交换式流形式的数据元素的相关标准规范。(序列化的元素对象利于数据传输和持久化)。简要说就是将可以响应式的数据,定义一套规范,在现有的网络协议上传输。

b.再来解释运行时环境,运行时环境需要按照标准来执行,具备相关接口或功能,从而使得开发者按照约定就能完成响应式编程。JS前端不说,JDK的具体标准如下:

https://github.com/reactive-streams/reactive-streams-jvm/blob/v1.0.2/README.md

标准很长,一般人没有必要去看。这里我想说,标准是工程师需要建立的思维模式。

关于异步非阻塞前文解释过了,异步非阻塞可以提升系统整体效率,这里又出现了回压(back pressure)的概念。

在响应式流中,数据流的发出者叫做Publisher(下文简称P),监听者叫做Subscriber(下文简称S)。如果一个P发布太快,S处理不过来,S将自己状态告诉P,这种机制就叫做回压,这时P可以将数据缓存,或者丢弃。


如何进行响应式设计

这部分因为我完全没有实践经验,所以容易赵括纸上谈兵,如有错误望请指正。

以Web后台为例,原MVC模式,是将功能分配给具体用户视图层展示,通常每个视图提供一种或一套功能页面,每个小模块可以向控制器通过ajax异步获取后台数据。响应式设计则将页面分成许多不同元素考虑,针对用户交互的需求,引发响应式流进行处理。从网上找到这样的图:

本文简要介绍了一下响应式编程,因为我也是刚学习一天,所以引用了许多他人的文章。主要是想把这种编程思想简单说一下,对于其技术优劣我不好评价,毕竟没有实践,但个人觉得比较适合于toCustomer程序,一方面异步非阻塞本身对效率就是提升,另外按照响应式设计的架构其模块利于微服务化,同时弹性较强耦合性较低。但是就想Spring官网说到,其实还有考虑团队技能,以Web为例传统的MVC不一定比Spring WebFlux差劲,就如同关系型数据库并不一定不如no-sql数据库。对于如何学习响应式编程,建议从Spring框架开始,多思考,多动手。


以上是关于浅谈响应式编程的主要内容,如果未能解决你的问题,请参考以下文章

浅谈前端响应式设计

[转帖]浅谈响应式编程(Reactive Programming)

浅谈 RSocket 与响应式编程

html 将以编程方式附加外部脚本文件的javascript代码片段,并按顺序排列。用于响应式网站,其中ma

浅谈RSocket与响应式编程

浅谈java响应式编程以及Reactor 3框架(内有福利)