架构设计80-落地实践07-响应式编程01

架构设计系列文章,请参见连接。

背景

响应式宣言

很早之前就想写Actor相关的介绍文章。怎奈没有好时机去介绍这部分内容。前几天准备研究一下Spring Cloud监控管理的内容,发现一个叫做Spring Boot Admin的项目。研究了一段时间后发现没有办法完美的解决我的问题,所以就准备研究一下改改代码。发现这个项目用了Spring的响应式编程的方法编写整个项目,所以这里就着这个机会把设计进行Actor介绍。

在接触Spring WebFlux之前,作者本人认为Actor其实是MapReduce的顶层的设计模式。可以为大量数据处理提供快速处理方案,并且解决线程管理工作。这两个问题都是程序员很难解决或者不愿解决的问题。后来想想其实在很多技术领域中都用到了这些概念。例如:JavaScript就是单线程事件驱动的模式完成了高吞吐量,libevent这种C语言的事件驱动库,基于libevent的memcached也是使用这种机制完成的,Nginx的实现方式也是基于这种模式去定义Work进程的。

  • 思考

从计算机被发明到现在,计算机主要处理两种问题:大量的吞吐和大量的计算。例如:在业界著名的C10K问题是关于大吞吐的问题,用户建模过程其实就是一个要求算力的问题。对于IO密集型和CPU密集型的处理方式和方法,需要进行思考与设计。在计算机专业的《算法导论》课上就是专门的解决这些问题的。对于通用型处理过程中的IO密集型和CPU密集型也需要有专业的解决方案以及统一的思维模式。故对于IO密集型和CPU密集型通用问题处理的思考:

Netty基于单线程设计的EventLoop能够同时处理成千上万的客户端连接的IO事件,缺点是单线程不能够处理时间过长的任务,这样会阻塞使得IO事件的处理被阻塞,严重的时候回造成IO事件堆积,服务不能够高效响应客户端请求。所谓时间过长的任务通常是占用CPU资源比较长的任务,也即CPU密集型,对于业务应用也可能是业务代码的耗时。这点和Node是极其相似的,我可以认为这是基于单线程的EventLoop模型的通病,我们不能够将过长的任务交给这个单线程来处理,也就是不适合CPU密集型应用。

那么问题怎么解决呢,参照Node的解决方案,当我们遇到需要处理时间很长的任务的时候,我们可以将它交给子线程来处理,主线程继续去EventLoop,当子线程计算完毕再讲结果交给主线程。这也是通常基于Netty的应用的解决方案,通常业务代码执行时间比较长,我们不能够把业务逻辑交给这个单线程来处理,因此我们需要额外的线程池来分配线程资源来专门处理耗时较长的业务逻辑,这是比较通用的设计方案。

换句话说,利用有限的线程,来充分利用多核的优势。

  • 方案

需要解决现实中的业务问题就需要进行。
事件驱动

设计模式

  • EventDelegate(事件委托)

在JavaScript和C#都有一种叫事件委托的编程方式。虽然这两种事件委托方式的机制不同,但是它为我们提供了关于发布/订阅的一种机制。提供了将事件发生和事件处理者之间进行隔离与解耦的机制,并为之后事件触发机制提供实现模式。

  • EventLoop(事件循环)

事件轮询和事件等待是事件处理的两种机制,事件循环的机制其实就是一种事件等待的机制。一般情况下使用*nix(linux,unix,win...)上提供的时间轮询机制降低CPU使用率又可以获取事件。对于EventLoop中由专门的事件接收处理,事件分发机制,事件业务处理。在单线程中进行相关的这三部分都在一个线程中完成。

  • Actor

Actor模型是1973年提出的一个分布式并发编程模式,在Erlang语言中得到广泛支持和应用。在Actor模型中,Actor参与者是一个并发原语,简单来说,一个参与者就是一个工人,与进程或线程一样能够工作或处理任务。可以将Actor想象成面向对象编程语言中的对象实例,不同的是Actor的状态不能直接读取和修改,方法也不能直接调用。Actor只能通过消息传递的方式与外界通信。每个参与者存在一个代表本身的地址,但只能向该地址发送消息。

  • Reactor

Reactor模式

Reactor模型:
1.向事件分发器注册事件回调
2.事件发生
3.事件分发器调用之前注册的函数
4.在回调函数中读取数据,对数据进行后续处理

  • Proactor

Proactor模式

Proactor模型:
1.向事件分发器注册事件回调
2.事件发生
3.操作系统读取数据,并放入应用缓冲区,然后通知事件分发器
4.事件分发器调用之前注册的函数
5.在回调函数中对数据进行后续处理

响应式编程的主流实现技术

目前,响应式编程的主流实现技术包括 Rxjava、 Akka Streams、Vert.x和Project Reactor等。

  • Rxjava
    Reactive Extensions(Rx)是一个类库,它集成了异步基于可观察( Observable)序列的事件驱动编程,最早应用于微软的NET平台。而 Rxjava是 Reactive Extensions 的Java实现用于通过使用 Observable/ Flowable序列来构建异步和基于事件的程序库,目前有1x版本和2.x版本两套实现。参考官网(http://reactivex.io/)

  • Akka Streams
    Akka也是响应式流规范的初始成员,而 Akka Streams是以Akka为基础的响应式流的实现,在Akka现有的角色模型之上提供了一种更高层级的抽象,支持背压等响应式机制。参考官网(https://doc.akka.io/docs/akka/2.5/stream/index.html)

  • Vert.x
    Vert.x是为了构建响应式系统而设计的,基于事件驱动架构, Vert x实现了非阻塞的任务处理机制。Vert.x中包含Vert.x Reactive Streams工具库,该工具库提供了Vert.x上响应式流规范的实现。我们可以通过Vert.x提供的可读流和可写流处理响应式流规范中的发布者和订阅者。参考官网(https://vertx.io/)

  • Project Reactor
    Spring 5中引入了响应式编程机制,而Spring5中默认集成了 Project Reactor作为该机制的实现框架。 Reactor诞生较晚,可以认为是第二代响应式开发框架。所以,它是一款完全基于响应式流规范设计和实现的工具库。WebFlux是一个典型非阻塞异步的框架,它的核心是基于Reactor的相关API实现的。参考官网(https://projectreactor.io/

总结

响应式编程和事件驱动模式有着密切的关系。它有事件驱动的很多特点:高性能,异步处理等。并为我们提供了并发能力与分发能力,这部分是大部分程序员都无法管理的内容。有了响应式编程后可以解决很多关于性能,关于异步拆分的功能。本文只介绍了异步编程的一点概念,接下来会深入的进行响应式编程的讨论。

参考:

反应式宣言
IO设计模式:Actor、Reactor、Proactor
aio_write - asynchronous write
eventloop & actor模式 & Java线程模型演进 & Netty线程模型 总结
响应式架构:消息模式Actor实现与Scala、Akka应用集成
实战SpringCloud响应式微服务系列教程(第三章)
Reactor 指南中文版V2.0
使用 Akka Actor 和 Java 8 构建反应式应用
使用 Akka 的 Actor 模型和领域驱动设计构建反应式系统

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

推荐阅读更多精彩内容