5 分钟理解什么是“响应式编程(Reactive Programming)”

背景

许多人都听过异步编程,同步编程,但是好像对响应式编程这个新名称感到很陌生,即使我们在实际项目中已经在使用这种编程方式。

这篇文章就是来介绍响应式编程(Reactive Progamming)到底是怎么回事。

如果我们在 Google 中输入 Reactive Programming,试图了解这到底是怎样的一种编程模式,我们很快会发现大量的文章,但是看完我们就会迷糊,概念还是不是那么清晰。这可能是因为许多介绍文章对领域的强关联导致的。比如最常见的一种介绍是用一种数据流(data stream)的方式来展现,还有就是前端领域的控件事件流,虽然这些场景是响应式编程适合的,但是对我来说,总觉得还是不够直观。因为我面对的是分布式系统的编程场景。

其实响应式编程没必要跟具体的应用领域关联,它是一个可以普遍适用的概念和编程模型。

同步与异步

分布式网络系统中,各个参与方节点的运行是相互独立的,没有共享内存,没有全局时钟。各节点通过消息来进行沟通。在传统的理念中,我们会把这样的网络根据他们通信方式描述成同步和异步的。简单来说,同步网络是对消息的到达时间有限定要求(time bounded),以便保证网络活动的确定性。而异步的网络,则对消息的到达没有任何限制。即使发出的消息丢失了,也不会损害网络的活性。用一个具体的例子来理解就是,节点 A 发送了一个消息给节点 B,期待得到 B 的回复,以便通过某个决议或者完成某件后续事情,这个依赖等待的要求,就是同步网络。因为他依赖一个答复才能进行后续动作。换句话说,如果一个节点发送消息之后,不依赖另一个节点的答复也能正常运行,那么就是异步网络。

在同步网络中,如果 B 由于网络原因(掉线,或者CPU繁忙,等等)没有在限定时间内回复,A 既不能确定消息已经发送给 B,也无法确定后续步骤什么时候才能开始,因此,网络活动变得不可预测,无法结束,也就是没有了确定性。业界已经证明了,在实际的网络中,如果不对网络条件施加任何限制,那么网络确定性是永远无法达到的。因此,为了保证网络活动的确定性,我们通常会网络条件施加一些限制,比如,最典型的就是消息到达的时间限制。

解释了同步网络和异步网络的区别,我们再来看同步编程和异步编程,其实我们接触这两个编程模式很久了。同步编程简单来说就是,发出一个任务,然后等待执行。而异步编程就是,发出一个任务,不等待结果,就继续发出下一个任务。至于上一个任务的执行结果,我们可以通过两种方式获得,一个是主动的轮训,另一个是被动的接收反馈。由于在异步编程中,我们从不等待执行结果,就可以进行其他任务(前提是这个任务本身不依赖上一个任务的结果)。如果要执行的某个其他任务依赖于上一个任务的结果,那么我们可以每隔一段时间轮训一次,或者另外开一个线程去等待接收任务结果。无论哪种情况,我们的网络都不会阻塞在某一个单独的任务上。

响应式编程

现在,我们很自然的过渡到响应式编程(Reactive Programming)这个概念上,它是一种基于事件模式的模型。在上面的异步编程模式中,我们描述了两种获得上一个任务执行结果的方式,一个就是主动轮训,我们把它称为 Proactive 方式。另一个就是被动接收反馈,我们称为 Reactive。

简单来说,在 Reactive 方式中,上一个任务执行结果的反馈就是一个事件,这个事件的到来将会触发下一个任务的执行。

这也就是 Reactive 的内涵!我们把处理和发出事件的主体称为 Reactor,它可以接受事件并处理,也可以在处理完事件后,发出下一个事件给其他 Reactor。两个 Reactors 之间没有必然的强耦合,他们之间通过消息管道来传递消息。Reactor 可以定义一些事件处理函数,根据接收到的事件不同类型来进行不同的处理。如果我们的系统复杂,我们还可以专门定义不同功能类别的 Reactors,分别处理不同类型的事件。而在每个 Reactor 中对事件又进行细分处理。

需要强调的是,实现 Reactive 模型最核心的是线程消息管道。线程用于侦听事件,消息管道用于 Reactor 之间通信不同的消息。与他们相关的是事件管理器用于注册、注销事件,而消息分配器则会根据消息类型分发。

下面是一个 Reactive 模型的示意图:

术语理解

在了解了上述异步编程模型的本质之后,我们再来看一些我们常见的术语,就会发现一切都变得清晰明了了。

比如,依赖链(Dependency chain),假定我们有一个事件依赖链是这样:睡觉 -> 吃饭 -> 饿了,很直觉的是,在这个依赖链中,只有满足了后面的条件,前面的才会执行。

这种依赖链是这个世界普遍的一种场景,一种正向的处理模式是,每隔一段时间就轮训检测是否满足睡觉的条件,在检查是否能睡觉的时候,会先检查是否已经吃饭,检查是否已经吃饭的时候,又会先检查是否饿了。那么这就是 Proactive 模式!而 Reactive 模式则反过来,先有事件的触发,然后事件来到响应方,响应方进行处理,这种方式也叫 Pub/Sub 模式。我们在 OOP 语言中,也会用到同样的概念和逻辑,我们把之叫做 Observer 模式,而在 Funcaitonal Programming 中,也有同样的概念,它可以用 monads 来实现。

比如,我们有一个 Publisher ,会产生 “饿” 事件,同时还有一个或多个 Subscriber,在收到 “饿” 事件的发生之后,进行响应(比如更新状态或者作出其他预先注册好的行为)。

总的来说,Reactive Programming 就是编写关于怎么响应事件的编程模式,这些事件包括:用户输入,数据流,系统状态的变化等等。

总结一下,响应式编程通常会用在一个事件流相关的场景中,在一个事件流中,一旦触发第一个事件,后续的事件会被依次触发,就像一个 Pipeline 系统,不断有输入和输出。

响应式编程的设计与实现

接下来,讲一下实现上的架构设计与实现。

通常 Reactor 的数量可以是预先定义的,因为一个系统,我们通常可以约束它处理哪些预定义的事件,比如有处理网络连接的 Reactor,处理日志收集的 Reactor,处理数据存储的 Reactor 等等,各司其职。而错误(未定义)事件则可以单独放在一个专门处理 Error/Exception 的 Reactor 中。通过事件管理器,每个 Reactor 可以根据要发出或者接收的消息,即时地创建一个线程/协程去执行响应的操作。发出和接收消息可以根据业务的复杂度,分开单独线程,也可以放在一个线程。这样的设计架构简单而清晰。

下面是一个简单的示意图:

全文完!

相关阅读:

P2P 网络核心技术:Gossip 协议
P2P 网络核心技术:UPnP 和 SSDP 协议
P2P 网络核心技术:Kademlia 协议

...

如果你喜欢我的文章,欢迎关注微信公众号“知辉”,搜索 “deliverit” 或

扫描二维码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容