主题三 · 系统架构设计师

事件驱动架构

Event-Driven Architecture (EDA) — 通过事件进行通信的软件架构

官方教程: 第 1 章 / 第 8 章 / 第 14 章 / 第 19 章
关联概念: Event Sourcing / CQRS
题型: 选择题 + ATAM 案例分析

01基础概念

事件(Event):是状态发生变化时软件发出的通知。

事件驱动架构(Event-Driven Architecture, EDA):是通过事件进行通信的软件架构。本质上是一种应用/组件间的集成架构模式

EDA 在五大典型架构中的位置

官方教程第 1 章将常用架构分为五类典型架构,事件驱动架构是其中之一:

分层架构

表现层 / 业务层 / 持久层 / 数据库

★ 事件驱动架构

通过事件通信,四大组件构成

微核架构

内核 + 即插组件(插件架构)

微服务架构

SOA 的升级,独立部署单元

云架构

处理单元 + 虚拟中间件

EDA 的关键特性

事件 ≠ 传统消息

事件和传统的消息不同,事件具有 schema,所以可以校验 event 的有效性;同时 EDA 具备 QoS 保障机制,也能够对事件处理失败进行响应。

02四大组成部分

官方教程第 1 章给出的标准 EDA 结构图,由四个部分组成:

事件
事件队列
分发器
↓ 通过事件通道分发 ↓
事件处理器 1
事件处理器 2
事件处理器 N
每个处理器内含若干模块
组件英文名说明
① 事件队列 Event Queue 接收事件的入口。保存系统中的事件并以先来先服务(FIFO)模式进行分派。能够存储任意时间内产生的事件,并支持检索以供将来处理。
② 分发器 Event Mediator 将不同的事件分发到不同的业务逻辑单元
③ 事件通道 Event Channel 分发器与处理器之间的联系渠道
④ 事件处理器 Event Processor 实现业务逻辑,处理完成后会发出事件,触发下一步操作。
对于简单的项目,事件队列、分发器和事件通道可以合为一体,整个软件就分成事件代理事件处理器两部分。

03云原生场景下的 EDA(第 14 章)

在云原生架构相关技术中,EDA 是七大主要架构模式之一(与服务化、Mesh化、Serverless、存储计算分离、分布式事务、可观测架构并列)。

典型的发布-订阅模型

生产者
— 事件 →
主题
— 事件 →
消费者
事件通过主题(Topic)进行发布-订阅,消费者按需订阅

核心机制

04★ EDA 的五大应用场景(核心考点)

事件驱动架构不仅用于(微)服务解耦,还可应用于以下场景中:

① 增强服务韧性

由于服务间是异步集成的,也就是下游的任何处理失败甚至宕机都不会被上游感知,自然也就不会对上游带来影响。

价值: 提升系统整体可用性,故障隔离。

② CQRS(Command Query Responsibility Segregation)

把对服务状态有影响的命令用事件来发起,而对服务状态没有影响的查询才使用同步调用的 API 接口

结合 EDA 中的 Event Sourcing 机制可以用于维护数据变更的一致性。当需要重新构建服务状态时,把 EDA 中的事件重新"播放"一遍即可。

③ 数据变化通知

在服务架构下,往往一个服务中的数据发生变化,另外的服务会感兴趣。

典型例子: 用户订单完成后,积分服务、信用服务等都需要得到事件通知并更新用户积分和信用等级。

④ 构建开放式接口

在 EDA 下,事件的提供者并不用关心有哪些订阅者,不像服务调用的场景——数据的产生者需要知道数据的消费者在哪里并调用它,因此保持了接口的开放性

⑤ 事件流处理

应用于大量事件流(而非离散事件)的数据分析场景,典型应用是基于 Kafka 的日志处理

补充:基于事件触发的响应

IoT 时代大量传感器产生的数据,不会像人机交互一样需要等待处理结果的返回,天然适合用 EDA 来构建数据处理应用

五大场景记忆口诀:韧 · C · 知 · 开 · 流
增强韧性 / CQRS / 数据变化通知 / 开放式接口 / 事件流处理

05EDA 与 Serverless 的关系

在云原生架构中,EDA 与 Serverless 紧密相关。Serverless 适用于事件驱动场景,但并非所有应用都适合 Serverless。

Serverless 不适用的场景

Serverless 适合的三类场景

① 事件驱动的数据计算任务

典型 EDA 场景与 Serverless 的完美结合

② 计算时间短的请求/响应应用

无需长时间维持上下文

③ 没有复杂相互调用的长周期任务

独立性强、调度简单

06Event Sourcing 事件溯源架构

Event Sourcing 架构模式由 ThoughtWorks 的首席科学家 Martin Fowler 提出。本质上是一种数据持久化的方式

Event Sourcing 的三个核心观点

  1. 整个系统以事件为驱动,所有业务都由事件驱动来完成。
  2. 事件是核心,系统的数据以事件为基础,事件要保存在某种存储上。
  3. 业务数据只是一些由事件产生的视图,不一定要保存到数据库中。

与 Lambda 架构的关系

Lambda 架构中数据集的存储使用的概念与 Event Sourcing 中的思想完全一致,二者都是在使用统一的数据模型对数据处理事件本身进行定义。

核心价值

这样在发生错误的时候,能够通过模型找到错误发生的原因,对这一事件进行重新计算以丢弃错误信息,恢复到系统应该的正确状态,以此实现了系统的容错性

07CQRS 命令查询职责分离

CQRS(Command Query Responsibility Segregation)架构分离了对于数据进行的读操作(查询)写(修改)操作。将能够改变数据模型状态的命令和对于模型状态的查询操作实现了分离。

CQRS 是领域驱动设计(Domain-Driven Design, DDD)的一个架构模式,主要用来解决数据库报表的输出处理方式。

CQRS 与 Lambda 架构的关系

Lambda 架构中:

为什么要读写分离?
读操作实际上比写操作要省时得多,如果将读和写操作放在一起,实际处理大量数据时会因为写操作的时长问题影响整体业务的处理效率。在大数据系统中经常处理海量数据,进行读写分离重要性不言而喻。

三者关系总结

架构提出者/出处核心思想
EDA 多年发展的架构风格 通过事件进行通信的软件架构,组件间集成的范式
Event Sourcing Martin Fowler / ThoughtWorks 数据持久化方式,事件是核心,业务数据是事件产生的视图
CQRS DDD 领域驱动设计 读写分离,命令(改状态)与查询(读状态)职责分离

08★ ATAM 评估案例:两个 EDA 实例(第 8 章)

官方教程第 8 章用两个事件驱动架构作为 ATAM 方法评估的完整案例:胡佛(Hoover)事件架构"银行"(Banking)事件架构

胡佛(Hoover)事件架构

胡佛事件架构由组成事件框架的组件和利用框架服务的应用程序组成。事件由两个主要部分组成:事件类型(Event Type)和事件需要处理的参数(Args)

胡佛架构的核心组件
  • 事件队列(Queue):保存系统中的事件,以 FIFO 模式分派。
  • 事件管理器(Event Manager):核心组件,绑定事件队列和事件类型(Type Bindings);维护事件类型注册表(Event Type Registry)数据结构,将事件类型注册到相关关联的处理程序中。一个事件可能关联多个处理程序。
  • Handler 组件:所有处理程序的基类,包含:
    • STOP handler:负责系统终止。
    • IDLE handler:执行"空闲等待",直到用户输入一个输入事件。

评估结论:主进程控制事件类型和应用程序的状态,也控制着事件管理器。具有高度的可修改性,每个组件可以独立出来并重新使用。

"银行"(Banking)事件架构

"银行"架构的特点
  • 事件有两个主要部分:类型(Type)及其参数(Args)
  • 事件队列(Queue):FIFO 模式;如果没有要返回的事件,则会生成"空闲"事件。
  • 基本处理程序(Handler):三个标准的指定处理程序组成:
    • START handler:在启动时初始化系统。
    • STOP handler:终止系统。
    • IDLE handler:验证输入事件是否有效。如果有效,则事件排队;否则会产生另一个空闲事件。
  • 主模块(Main):框架的一部分。将事件管理器和事件队列绑定到一起。从事件队列中取出一个事件并将其分派给事件管理器进行处理。

两种架构的差异(质量属性视角)

质量属性胡佛架构"银行"架构
可修改性 高(每个组件可独立重用) 较差(事件管理器暴露给应用程序,没有封装)
可重用性 较好 较差(组件高度相互依赖,互相协同完成功能)
可靠性 较好(在初始阶段就消除有缺陷的输入)
额外开销 较低 较高(空闲事件需要额外处理空间)

ATAM 评估中涉及的利益相关者

评估这两种架构时考虑的主要利益相关者包括三类:

关键质量属性场景(来自利益相关者)

用户
针对系统的未授权访问
安全性
用户
所有操作以尽可能快的速度处理
性能
用户
失效发生后应该立即回复
可用性
用户
处理使用系统过程中的用户错误
可靠性
架构师
处理针对系统功能的新需求
可修改性
架构师
框架的主要部分应该支持重用
可变性
架构师
框架的修改开销小、速度快、时间短
可修改性
架构师
框架中的组件能够协同交互
功能性
架构师
框架能够扩展以支持更复杂的选项
可变性
架构师
可以在不同环境中执行
可移植性
开发者
合适的数据封装和安全的数据结构
安全性
开发者
可以用其他编程语言灵活实现
可移植性
开发者
架构层面上期望有着全局一致的行为
概念一致性
开发者
框架应该完整、清晰并与需求一致
功能性

ATAM 评估四阶段在 EDA 案例中的应用

阶段关键步骤说明
阶段 1 演示 第 1 步:介绍 ATAM 评估负责人提供 ATAM 过程的一般信息,说明分析技术与预期结果。
第 2 步:介绍业务驱动因素 定义被评估系统的主要功能,涉及的利益相关者。
第 3 步:介绍要评估的体系结构 架构团队描述要评估的架构,侧重于体系结构、时间可用性以及质量要求。
阶段 2 调查与分析 第 4 步:确定架构方法 理解系统关键需求的关键架构方法,解释架构的流程控制。
第 5 步:生成质量属性效用树 以"效用"作为根节点,质量属性构成辅助级别,叶节点是质量属性说明。优先级排名为高(H)、中(M)、低(L)
第 6 步:分析体系结构方法 找出风险、非风险、敏感点和权衡点。
ATAM 评估两个 EDA 案例(胡佛 vs 银行)在历年案例分析题中出现频率较高,务必掌握:
1. 两个架构的结构差异(关键看事件管理器是否被框架封装)
2. 质量属性场景与利益相关者的对应关系
3. 优先级 (H, M, L) 的判断:对系统成功的重要性 + 对架构师的难易度

09考点速记卡

事件 vs 消息的核心区别

事件具有 schema,可校验有效性 + 具备 QoS 保障机制(可对处理失败响应)

EDA 四组件记忆图

事件 → 队列分发器通道处理器

简单项目可合并为:事件代理 + 事件处理器

EDA 五大应用场景速记口诀

韧 · C · 知 · 开 · 流

增强韧性 / CQRS / 数据变化通知 / 开放式接口 / 事件流处理

EDA 三兄弟概念辨析

EDA = 架构模式(整体框架,事件驱动通信)

Event Sourcing = 数据持久化方式(Martin Fowler 提出,事件是核心)

CQRS = 读写分离(DDD 模式,命令/查询职责分离)

胡佛 vs 银行 关键差异

胡佛架构:事件管理器在框架内,封装良好 → 可修改性强

银行架构:事件管理器暴露给应用 + 组件高度依赖 → 可修改性、可重用性都较差,但可靠性较好(初始就过滤错误输入)

易混淆点 · 必须记牢
  • EDA 是异步集成 —— 下游失败上游无感(增强韧性的根本原因)
  • CQRS 中,命令用事件,查询用同步 API(不要混淆)
  • Event Sourcing 的"播放":重新执行历史事件以重建状态
  • 事件流 vs 离散事件:事件流处理适用于 Kafka 等海量日志场景
  • IoT 天然适合 EDA:传感器数据无需等待返回结果
  • Serverless 不适用的三种情况:有状态、长时间密集计算、频繁外部 I/O
案例分析答题套路:
对于 EDA 相关案例题,可按以下框架展开:
1. 识别架构组件:事件队列、分发器、通道、处理器是否齐全?
2. 评估同步/异步:是否真正实现异步集成?
3. 检查解耦程度:发布者是否需要知道订阅者?
4. 列举质量属性:可修改性、可重用性、可靠性、性能
5. 识别敏感点/权衡点:事件队列容量、处理器并发能力等