架构设计系列文章,请参见连接。
介绍
还是先举例子,在平常的生活中事件驱动架构也是比较常见的。一般情况下的人与人之间的沟通都是以一个人说一个人听的关系进行,并同时可以交换听者与说着。伴随着听者听到说者所表述的内容后,做出的心理,行为上的反应就是事件在接受者中的处理过程。
上面简单的说明了事件驱动的机制。我们从中找一些抽象出事件驱动架构模式的特点。在上面简单的例子中我们可以分析出说者和听着都是独立的个体,独立个体就有独立的思维方式以及处理结果。通过两者都能理解或者都能听懂的语言进行交流,双方都能理解的语言在计算机系统中可以定义为通信协议。双方是通过声音的方式进行沟通的,那么双方的通讯是需要在通信介质(空气)上进行的。
如上所述,我们总结出事件驱动架构模式的几个重要特点。
- 至少需要一个发送者和一个接受者。
- 需要在两者之间建立双方都可以理解的通信协议。
- 需要传播介质帮助信息的传递的过程。
在这里就有可能碰到很多问题。比如说:一个人自言自语,算不算事件驱动机制?一个人在台上演讲,台下做了很多人算不算事件驱动?在于不同语言的人沟通时中间介入的翻译算不算事件驱动?我使用电话和家人通话算不算事件驱动?我看电视剧算不算事件架构模式?
讲解
上面提到了很多的问题,其实这里涉及到比较多的现实编程中会遇到的问题。一个真正的事件驱动架构模式是不必要关心这些问题的。因为事件架构模式最重要的事产生事件和处理事件。只要专注于此即可,不必拘泥于这么多的情况。
事件驱动架构模式中的两件核心事情:产生事件和处理事件。接着分析这两个核心问题,怎样产生事件?怎样处理事件?
产生事件可以分为:
- 事件触发事件。在这里并不一定是同一种方式出发的事件再转发出去。例如,可以是用户从页面触发的事件,然后转换成消息队列中的消息事件,然后再转换成写库事件。它不必是从rest来的事件再转换成另外一个rest事件传递给其他的接收者。
- 定时事件。在很多情况下业务系统需要定时处理某些业务。
- 随机事件。随机事件是一类比较特殊的事件产生情况,但在一些特殊的情况下需要差生一些随机事件。混沌工程,MonkeyKing的场景下需要产生某些随机事件。
处理事件一般情况下不进行分类,因为基本上都是进行业务处理然后返回。就像早先在单体结构中,一个WEB服务接收到客户的HTTP事件之后进行处理类似。所以业务处理系统无法进行分类。不过与一般的事件处理不同的是事件驱动架构模式内定义了更多的消息通信方式:同步消息,异步消息。同步消息就是在接收者接收到消息之后处理消息并返回的过程中,发送者一直等待直到结果返回。异步消息则不同,异步消息在消息发送者发送完消息后就不等待,直接处理其他事务即可。
模式描述
最早之前在学习MFC的时候,就认为每个按钮,每个动作绑定一个事件处理函数的方式就是一种实践的处理方式。后来在浏览器上用JS监听鼠标,按钮动作时就又发现了一种事件驱动模式,并且现在流行的Nodejs把JS的单线程事件驱动模型给发挥的淋淋尽致。再有使用Socket通信时的Select,Poll也是标准的事件驱动模型,在Linux上还有专门的事件驱动库Libevent。可知道在Linux上找到一个用C语言写的库是非常非常难的(除了LibC)。可见事件驱动模式在计算机技术发展过程起到了多大的作用。
在现在流行的移动端开发中,也有Android消息机制,从Java层到Native层剖析,Android消息机制(一):概述设计架构这样的事件驱动模型。然后配合FSM(有限状态机)影响移动系统的状态是非常强的一种架构模式。
在Java企业应用系统中也有spring events 和 eventbus帮助我们形成企业应用系统。而且借助工具可以在应用内部实现事件驱动,也可以在应用外部实现事件驱动。
业界有很多把事件驱动模式又划分为Mediator拓扑和Broker拓扑。这里我只接受Mediator拓扑。因为Broker拓扑只不过就是将事件处理系统级联起来,组成一个级联事件处理系统。我们大可以用管道过滤器架构模式来级联不同的事件。另外也因为架构模式是一种原则性或规则性的概念,所以,只需要介绍最纯粹的原则即可,不能介绍具体的实现。如果介绍具体实现会限制读者在接收信息时的接收到的元信息。
特点
开发
- 过程管理(康威定律)
事件驱动架构模式一个比较大的特点就是消息的可跟踪性弱,所以,需要考虑在哪里加入跟踪元素,跟踪元素的实现团队与使用事件驱动模式的团队之间的关系。
- 可测试性
因为事件驱动模式的事件可跟踪性弱的原因。在测试中需要以事件为判断因素时可测试性较弱,并且如果出现问题调查起来也比较困难。
- 可扩展性
因为使用分离关注点的方式隔离了两端,如果使用消息中间件进行隔离可以得到很好的可扩展性。
运维
- 可伸缩
变体比较多,有些变体可以适应伸缩,有些变体不适用伸缩。
- 部署难易
有些变体中有设计到多服务部署和服务发现的问题,需要在上线时进行配置。
- 维护难易
稳定性尚可,但是可跟踪性比较弱。所以维护难度比较高。
性能
这里需要看性能是按照那些标准进行计算。主体上来说,事件驱动架构模式对性能的影响不会太大。
总结:
- 通信方式中单播,组播,广播都可以在事件驱动架构模式中使用。
- 可以在架构中使用独立的服务组件(消息中间件)完成消息的传递,也可以使用服务内部的事件驱动框架完成。
- 在涉及到服务部署多节点时,但某项业务需要只处理一遍时。可以借助外部的决策中心进行决策,由主节点完成处理,辅节点可以不处理。也可以使用调度中心进行调度。
参考:
《恰如其分的软件架构.风险驱动的设计方法》14.11 发布-订阅风格
阿里巴巴在混沌工程领域的实践和思考
Software Architecture Patterns
构建事件溯源系统时犯的错误和恢复措施