何为EDA
- 事件驱动架构是一种异步分发事件的架构模式
- 用于高扩展且低耦合的系统
- 以事件为核心,一系列解耦的、单一功能的事件处理器
Notification
- 源系统发送消息通知其他系统状态改变
- 接收方响应非必须
- 发送 Event 逻辑与处理 Event 逻辑无依赖,独立变化
- 解耦,各自扩展
Carried State Transfer
- 源系统推送消息及变化
- 依赖者生成信息副本
- 容错(fault tolerance)
- 源系统不可用时,依赖者可以使用副本
- 依赖者维护信息副本和变化
- 数据冗余
- 数据一致性
- 提高整体性能
- 依赖者直接使用信息副本
经典应用 NIO
- 针对不同的 IO Event 分配不同的 handler
- Selector:监控那些Channel 有 IO Event
- SelectionKey:维护 IO Event 的状态和绑定的 handler
经典应用 Nginx
- Nginx 的工作进程一直监听端口并等待 Event
- Event 是由新建立的连接所触发
- 所有的连接都会被分配到一个对应的状态及
- Non-blocking
EDA:两种Topology
Mediactor中介模式
- 存在业务流程
- 多步骤
- 统一协调,居中调度
- 事件分层次
Event Queue
- 源系统将 event 发送到 queue
- event 处理系统从 queue 中消费 event
- 源系统和事件处理系统的连接点
- queue 只关心事件的传输
Event Mediactor
- 中介从 queue 中消费原始事件,并分配、协调各个执行步骤
- 对应业务处理的每个步骤,产生待处理事件(业务事件)
- 将待处理事件异步分发到不同的通道(channel)
- 无具体业务逻辑,只知道有哪些步骤
Event Channel
- Mediator 向 channel 发送消息,processor从channel读取
- 某种业务事件(消息)的聚合
- 多个processor可以监听同一个channel
Event Processor
- 监听channel的event
- 具体的、单一功能的业务逻辑单元
- 处理器之间无关联性
- 所有处理器合作形成完整的业务流程
Mediactor模式应用场景
Broker代理模式
- 无中心控制器
- 轻量的消息代理将消息串联成链状
- 分发至事件处理器组件
- 事件处理器独立运作
Broker
- 轻量级的代理
- 无业务逻辑的简单消息分发
- 源系统将event发送至代理(通道)供processor消费
- 事件通道可以是queue,topic或两者的组合
Event Processor
- 监听channel的event,判断是否处理
- 处理一个事件,发送一个事件,标明其行为
- 事件处理器,单一业务逻辑
- 处理器无关联性,不构成业务逻辑链
应用:订单状态日志记录
EDA模式优缺点
优点
- 灵活性
- 架构能在不断改变的使用场景下快速响应
- 事件处理器组件目的单一、高度解耦,可以独立变化
- 代理拓扑结构比中介拓扑结构调度更容易
- 可扩展性
-
高度解耦,独立变化
-
横向扩展
- 不同组件的运行结点数可自行调整
- 组件本身可以自行决定是否再拆分实现
-
纵向扩展
- 计算密集型还是内存密集型,按需调整
-
- 性能
- 细粒度的事件处理器有利于提高性能
- 整体架构是异步并行有利于提高性能
- 易于部署:高度解耦的事件处理器组件让整体部署相对容易
缺点
- 可测试性
- 单元测试无差异
- 集成测试难
- 组件众多
- 异步
- 可维护性
- 分布式部署
- 异步:对程序员要求高一些
- 异常处理难
- 代码可读性
- 性能:分布式消息(事件)传递会降低性能
真实案例分析
短信验证码
电商订单生命周期管理
数据同步消息广播
面试
电商系统下单成功,如果有风控问题,需要客服接入,如何设计
思考深度和实现层面:考虑未来可能出现的问题,留下可扩展的接口
- 目前提出的是风控问题,后续还有可能有其他问题,包装成一个事件,广播出去,只要是需要处理这个事件的都可介入处理,保障系统的可扩展性和灵活性
淘汰老系统,如何实现双写
- 把所有涉及到更新和添加的操作封装成一个事件,广播出去
- 任何一个通过网络传输的东西都有丢失的风险,分布式系统下的一致性问题需要考虑,有可能发送源失效;也有可能发送成功但是没有收到广播;也有可能收到广播,但是还没有做操作,系统挂了。
- 还需要考虑后续需要有一个类似于对账的系统,对比两个数据的一致性问题