Event-driven architecture (EDA) is a software architecture paradigm promoting the production, detection, consumption of, and reaction to events. - Wikipedia

什么是事件驱动架构?

维基百科的定义,事件驱动架构(EDA)是一种软件架构范式,促进事件的产生、观测、消费和反应。

在认识事件驱动架构之前,先来明确一下,什么是事件。

事件是已经发生的事实,并且不可变。例如,“创建订单”是个指令,而“订单已创建”就是个事件,订单的信息、订单创建的时间,在这个事件发生后就无法被修改。

在传统的架构体系下,编程思维可以说是过程驱动的,一个指令触发了一段逻辑,这其中可能包含了几个不同的方法行为,它们之间按照过程顺序来编排、嵌套。看起来似乎很清晰,但是很容易写出长长的“面条”代码。而事件驱动架构则强调了事件的产生与消费,将逻辑的过程转换为事件之间的环环相扣。

事件驱动架构。png

就如上图所展示的,如果采用事件驱动架构,订单服务就只负责订单的创建,然后发出“订单已创建”的事件,交由 EventBus 路由,转发给关心这个事件的各个监听者。

在我的开发经历中,也有采用事件驱动架构的项目,接下来,就结合自身经验,总结一下 EDA 的优缺点和其适用场景。

EDA 的优点

解耦

首先,解耦是事件驱动架构所带来的最明显的优点。从上述的例子中就可以看出,采用了 EDA 后,订单服务只需要负责处理对应的业务逻辑,而其他的切面逻辑,例如操作记录、发短信等,都可以通过事件的通知机制来解耦,从而保证业务逻辑的简洁、专注。并且,这些切面功能点可以考虑使用异步处理,也能很好地提升系统的响应能力。

DDD 与事件风暴

在领域驱动设计(DDD)中,如果采用 以“领域事件”为核心的建模思路,与业务人员通过事件风暴的形式来梳理业务流程,就会得到一系列的事件列表,也就是事件驱动架构中的所有事件。从业务人员到开发人员,从真实业务逻辑到系统设计实现,都以这些事件为核心,就能够形成统一语言,方便沟通和理解。

事件溯源

事件上存储了必要的信息和时间,如果将所有的事件持久化,结合最初的实体信息,你就拥有了一台来去自如的时光机。例如在一个资产管理系统中,存储了“资产已入池”、“资产归属已变更”、“资产已出池”等所有的事件,并且存储了资产初始化时的快照数据,就可以根据快照数据和给定时间范围内的事件列表,重新计算出某个时间的资产数据,这就是事件溯源。如果整个生命周期中事件量很大,可以考虑定期给实体做快照,溯源时获取最近的一份快照数据。事件溯源能给业务提供更灵活的数据支撑,同时,因为存储了所有的事件数据,也保障了系统的故障恢复能力和数据一致性。

EDA 的缺点

系统复杂度

“在软件工程中,没有一个中间层解决不了的问题”,事件驱动架构,就是通过引入中间层 EventBus 来实现事件机制,看似能带来不少诱人的优点,也必然会增加系统的复杂度。Spring 虽然有提供事件机制,但是比较简单,如果有复杂的使用场景,得考虑自己实现。

事件驱动架构改变了编程思维,一切都围绕事件的发布和订阅,将完整的功能过程,拆解为了不同的事件,也丧失了过程驱动带来的叙事能力。如果事件数量众多,就容易在“事件丛林”中迷了路。

使用场景

软件工程没有银弹,事件驱动架构也有其适用的场景,结合上述优缺点,个人认为,以下几个方向可以考虑采用 EDA:

  • 组件解耦(消息推送、操作记录等)
  • 数据沉淀系统(审计、资产等)

常规的业务逻辑里,如果有一些切面组件,例如消息、操作记录,可以接入轻量的 EDA 来解耦,保证业务逻辑清晰和职责的单一;而在数据沉淀系统中,例如审计、资产等领域,通常没有特别复杂、长链路的业务逻辑,由业务系统来触发更新数据,更关注的是数据的准确性、一致性,就可以考虑使用 EDA 和事件溯源机制。