本文将探讨如下几个问题:
- Event-Driven架构风格的约束
- EDA风格对架构属性的影响
- Reactor架构模式
- Reactor所解决的问题
- redis中的EventDriven
从观察者模式到EDA风格
GOF的23种设计模式中,有一个观察者模式!个人觉得叫「监听模式」更合理!
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。

它和EDA风格有些类似!不过一个应用在代码关系层面;一个应用在架构上!
在EDA中,有三个必要组件:
- 事件生产组件:对应到观察者模式中,就是引起Subject状态变化的对象。它引起Subject状态变化的动作就是事件。
- 事件队列:对应到观察者模式中,就是Subject对象。事件生产者产生的事件,会到事件队列中。
- 事件处理组件:处理事件生产组件所产生的事件。对应到观察者模式中,就是Observer对象。
EDA风格的约束
- 「事件生产组件」产生事件,将其添加到「事件队列」中
- 「事件处理组件」监听「事件队列」
- 当「事件队列」中有自己能处理的事件时,「事件处理组件」将对该事件进行处理
- 「事件处理组件」处理完事件后,可以将处理结果返回给「事件生产组件」,也可以不返回
- 「事件生产组件」可以接收「事件处理组件」处理结果,也可以不接收
EDA风格可以细分为Mediator结构和Broker结构!
- Mediator结构通过一个Mediator组件协调多个步骤间的关系和执行顺序
- Broker结构则是通过松散的方式来组织多个步骤之间的关系和执行顺序
Mediator结构如下:

在Mediator结构中主要有四个组件:
- 事件队列(event queue)
- 事件中介(event mediator)
- 事件通道(event channel)
- 事件处理器(event processor)。
执行流程如下:
- 「事件生产组件」产生事件,将其添加到「事件队列」中
- 「事件中介」监听「事件队列」
- 当「事件队列」中有事件时,「事件中介」根据具体的事件,将其拆分/组合为一步步的具体步骤
- 将具体的步骤添加到对应的「事件通道」中
- 「事件处理器」从「事件通道」中获取到事件,进行处理
Broker结构如下:

Broker结构中主要包括两个组件:
- Broker:Broker可被集中或相互关联在一起使用,此外,Broker中还可以包含所有事件流中使用的事件通道。
- 事件处理器
执行流程如下:
- 「事件生产组件」产生事件,将其添加到「Broker」中
- 「事件处理组件」监听「Broker」
- 当「Broker」中有自己能处理的事件时,「事件处理组件」将对该事件进行处理
- 「事件处理组件」处理完事件后,发送后续事件到「Broker」中
- 其它「事件处理组件」接收到自己能处理的事件后,对该事件进行处理,处理完后,可能继续发送事件到「Broker」中
- 当不再有后续事件时,所有步骤完成
EDA风格对架构属性的影响
- 性能:由于EDA是个异步架构,对于不需要返回值的请求,它能明显的提高用户可感知的性能。
- 扩展性:事件生产者和事件消费者松耦合,可以独立进化,可以方便的进行功能扩展。同时由于,可以方便的添加事件消费者,故而进一步提高了扩展性。
- 伸缩性:事件生产者和事件消费者松耦合及可以方便的添加事件消费者,使得EDA有很好的伸缩性
- 可维护性:事件生产者和事件消费者松耦合,且和一般的调用方式相比,在理解上有一定的难度,使得开发难度增加,但单元测试较方便。而由于EDA的异步性,使得集成测试比较麻烦。可维护性一般
- 可运维性:事件生产者和事件消费者松耦合,可独立部署,可运维性相对较容易
- 灵活性:高度可扩展,易于伸缩使得EDA有较高的灵活性
Reactor架构模式
Reactor架构模式,是EDA风格的一种实现!它是为了处理:
- 高并发IO请求
- 其中请求所包含的数据量不大
- 每个请求处理耗时不长
Reactor模型,有四个组件:
- Acceptor:Acceptor接受Client连接。属于EDA「事件队列组件」。
- Channel:接收IO事件。属于EDA「事件队列组件」。
- Reactor:监听Channel和Acceptor,当发生连接事件或IO事件时,将其派发给对应的Handler。属于EDA「事件队列组件」。
- Handler:和一个Client通讯的实体,进行实际的业务处理。对应EDA的「事件处理组件」。
Client属于EDA的「事件生产组件」!
Reactor可以分为:单线程模型,多线程模型和主从Reactor模型。
- 单线程模型
Reactor轮询到消息后,就直接委托给Handler去处理,处理完后,再进行后面的轮询,即一个Handler处理完之后,才能进行下一个Handler的处理!如果某个handler耗时较长,就会阻塞后续的handler的执行!
