2. 核心概念解析:事件、事件源、事件处理器、事件总线
好,咱们正式开始聊策略引擎里最核心的四个概念。这四个东西,说白了就是事件驱动架构的「四根柱子」。你把这四个概念吃透了,后面写代码、搭系统,心里就有底了。
我个人习惯,每次带新人做项目,第一件事就是让他们把这四个概念画在纸上。画不清楚,代码肯定写不明白。嗯,咱们一个一个来。
2.1 事件(Event)—— 系统里发生的「一件事」
事件是什么?说白了,就是「已经发生的事实」。比如用户下单了、支付成功了、库存扣减了、风控规则触发了……这些都是事件。
在代码里,事件通常是一个不可变的对象。它记录了三样东西:
- 发生了什么(事件类型,比如 OrderCreated)
- 什么时候发生的(时间戳)
- 相关的数据是什么(事件载荷,比如订单ID、金额)
我在项目中遇到过一种坑:有人把事件设计成可变的,后面到处改它的字段。结果调试的时候,根本搞不清事件到底是谁改的。所以我的建议是——事件一旦创建,就别再动了。
核心原则:事件是不可变的。 你只能读它,不能改它。想改?那就发一个新事件。
来看一个简单的事件定义:
// 一个典型的事件对象
public class OrderCreatedEvent {
private final String eventId; // 事件唯一ID
private final long timestamp; // 发生时间
private final String orderId; // 订单ID
private final double amount; // 订单金额
// 构造函数、getter方法……省略
}
你想想看,如果这个事件被改了,后面的事件处理器拿到的数据就不对了。整个链条都会乱掉。所以,事件就是事实,事实不能改。
2.2 事件源(Event Source)—— 谁发出了这个事件?
事件源,就是事件的「生产者」。谁产生了这个事件,谁就是事件源。
在策略引擎里,事件源可以是:
- 用户操作(比如前端点击了「提交订单」按钮)
- 外部系统(比如支付网关回调说「支付成功」)
- 定时任务(比如每天凌晨触发的「结算事件」)
- 系统内部(比如规则引擎执行完一条规则后,发出「规则命中事件」)
我记得有一次,一个同事把所有事件源都混在一起,结果出了问题根本查不到是哪个模块发的。后来我们强制要求:每个事件必须携带事件源标识。这样出了问题,一眼就能定位。
小技巧: 在事件里加一个 source 字段,写上模块名或服务名。比如 "order-service"、"payment-gateway"。排查问题的时候,这个字段能救命。
2.3 事件处理器(Event Handler)—— 谁来处理这个事件?
事件处理器,就是事件的「消费者」。它负责响应事件,执行具体的业务逻辑。
比如:
- 订单创建事件 → 处理器去扣库存
- 支付成功事件 → 处理器去发邮件通知用户
- 风控规则触发事件 → 处理器去冻结账户
每个处理器只关心自己感兴趣的事件类型。不相关的事件,它根本不理。
我曾经犯过一个错误:在一个处理器里写了太多逻辑,结果它既要处理订单事件,又要处理支付事件,还要处理库存事件。代码变得又臭又长,改一个地方,其他地方跟着出问题。
避坑指南: 一个处理器只处理一种事件类型。如果发现一个处理器里塞了太多 if-else,说明该拆分了。我曾经因为没拆分,导致线上事故,教训深刻。
来看一个处理器示例:
// 订单创建事件的处理器
public class OrderCreatedHandler implements EventHandler<OrderCreatedEvent> {
@Override
public void handle(OrderCreatedEvent event) {
// 1. 扣减库存
inventoryService.deduct(event.getOrderId());
// 2. 发送通知
notificationService.sendOrderConfirmation(event.getOrderId());
// 3. 记录日志
logger.info("订单创建事件处理完成: {}", event.getOrderId());
}
}
你看,这个处理器只做一件事:处理订单创建。逻辑清晰,出了问题也好排查。
2.4 事件总线(Event Bus)—— 连接事件源和事件处理器的「高速公路」
事件总线,就是事件源和事件处理器之间的「桥梁」。它负责:
- 接收事件源发出的事件
- 找到所有对该事件感兴趣的处理器
- 把事件分发给这些处理器
- 处理异常、重试、超时等问题
说白了,事件总线就是整个事件驱动架构的「交通枢纽」。没有它,事件源和处理器就得硬编码耦合在一起。有了它,两边就解耦了。
我习惯把事件总线想象成一个「邮局」:事件源是寄信人,事件处理器是收信人,事件总线就是邮局。寄信人不用知道收信人是谁,收信人也不用知道信从哪来。邮局负责把信送到该去的地方。
事件总线的核心价值:解耦。 事件源不关心谁在处理事件,处理器不关心事件从哪来。两边只跟事件总线打交道。
下面我用一张 SVG 图来展示这四个概念的关系:
这张图很直观:事件源产生事件,事件发布到事件总线,事件总线把事件分发给所有感兴趣的处理器。整个过程是异步的、解耦的。
2.5 四个概念的关系总结
咱们用一张表格来总结一下:
| 概念 | 英文 | 角色 | 核心职责 |
|---|---|---|---|
| 事件 | Event | 数据载体 | 记录「已经发生的事实」,不可变 |
| 事件源 | Event Source | 生产者 | 产生事件,发布到事件总线 |
| 事件处理器 | Event Handler | 消费者 | 响应事件,执行业务逻辑 |
| 事件总线 | Event Bus | 中介 | 接收事件,分发给处理器,解耦双方 |
我的经验: 刚开始学事件驱动架构时,别急着上框架。先用一个简单的队列(比如内存队列)把这四个概念跑通。理解了它们的关系,后面用 Kafka、RabbitMQ 这些工具,就是换一个「事件总线」的实现而已。
嗯,这四个概念就讲到这里。你想想看,是不是挺清晰的?事件源只管发,处理器只管收,事件总线在中间做调度。各司其职,互不干扰。这就是事件驱动架构的魅力所在。
公众号:蓝海资料掘金营,微信deep3321