4. 事件驱动架构模式:发布-订阅模式、事件流模式、CQRS与事件溯源简介
好,咱们进入第四章。这一章我打算聊聊事件驱动架构里几个最核心的模式。说实话,很多刚接触事件驱动的同学,容易把「发布-订阅」和「事件流」搞混,更别提CQRS和事件溯源了。别急,我一个一个拆开讲。
4.1 发布-订阅模式:最基础的解耦利器
发布-订阅模式,说白了就是「我不直接找你,我喊一嗓子,谁爱听谁听」。这个模式在策略引擎里太常用了。
核心角色有三个:
- 发布者(Publisher):只管发出事件,不关心谁消费
- 订阅者(Subscriber):只关心自己感兴趣的事件类型
- 事件通道(Event Channel):中间的消息代理,负责路由
我在项目中遇到过这样一个场景:策略引擎需要实时监控多个风控指标。每个指标变化时,都要通知多个下游系统。如果用传统的接口调用,代码会耦合成一团乱麻。用发布-订阅就清爽多了——指标模块只管发布「指标变更事件」,风控、报表、告警各自订阅自己需要的部分。
关键点:发布-订阅模式的核心价值是时间解耦和空间解耦。发布者不需要知道订阅者存在,订阅者也不需要知道发布者是谁。
嗯,这里要注意:发布-订阅虽然解耦,但也会带来「事件风暴」的风险。我曾经见过一个系统,一个事件触发后,连锁反应导致几十个订阅者同时执行,直接把数据库打挂了。所以,一定要做好背压和限流。
4.2 事件流模式:从「点对点」到「持续流动」
发布-订阅是「一次发布,多点消费」。事件流模式则更进一步——它把事件看作一条持续流动的数据河。
你想想看,在策略引擎里,规则评估往往不是一次性的。比如用户行为分析,需要连续观察用户的一系列操作:点击、滑动、停留、退出……这些事件是有顺序、有状态的。事件流模式正好适合这种场景。
事件流 vs 发布-订阅:
| 维度 | 发布-订阅 | 事件流 |
|---|---|---|
| 事件顺序 | 不保证顺序 | 严格保序 |
| 持久化 | 通常不持久 | 持久化存储 |
| 重放能力 | 无 | 支持回溯重放 |
| 典型实现 | Redis Pub/Sub, RabbitMQ | Kafka, Pulsar |
我个人习惯在策略引擎里这样用:实时规则评估用发布-订阅,历史分析和状态恢复用事件流。两者互补,不冲突。
避坑指南:我曾经把Kafka当普通消息队列用,结果发现消费组配置不对,导致同一个事件被重复处理。记住:事件流模式里,分区是并行度的关键,同一个分区内的事件顺序是保证的,跨分区则不保证。
4.3 CQRS:读写分离的哲学
CQRS(Command Query Responsibility Segregation)——命令查询职责分离。名字挺长,道理很简单:写数据和读数据,用不同的模型。
为什么需要这样?我举个例子。在策略引擎里,规则配置的写入需要严格的校验和事务,但读取规则时,我们希望毫秒级响应。如果读写共用同一个模型,要么写模型拖慢读性能,要么读模型限制写灵活性。
CQRS的核心原则:
- 命令(Command):改变状态,不返回数据
- 查询(Query):返回数据,不改变状态
- 模型分离:写模型用领域驱动设计,读模型用扁平化视图
嗯,这里要注意:CQRS不是银弹。如果你的系统读写比例接近1:1,或者业务逻辑极其简单,强行CQRS反而增加复杂度。我一般只在读远多于写,或者读写性能要求差异巨大的场景下才用。
警告:CQRS带来的最大挑战是数据一致性。写模型更新后,读模型需要同步。这个同步过程通常有延迟,也就是「最终一致性」。如果你的业务要求强一致性,CQRS可能不适合你。
4.4 事件溯源:把状态变成事件日志
事件溯源(Event Sourcing)是我个人非常喜欢的一个模式。它的思想很颠覆:不保存当前状态,只保存所有发生过的事件。
举个例子。传统方式保存用户余额:直接存一个数字「100元」。事件溯源的方式:存「存入50元」「取出20元」「存入70元」……当前余额是多少?把事件从头到尾重放一遍就知道了。
事件溯源的优势:
- 完整的审计日志:每个状态变化都有记录
- 时间旅行:可以回到任意历史时刻的状态
- 事件驱动天然适配:事件既是存储单元,也是通信单元
我在项目中遇到过这样一个需求:金融风控策略需要回溯「某个规则在特定时间点生效时的评估结果」。如果用传统方式,你得记录每次策略变更的快照,非常麻烦。用事件溯源就简单了——把规则变更事件存下来,需要时重放到那个时间点即可。
关键点:事件溯源通常和CQRS搭配使用。事件存储作为写模型,然后通过事件投影(Projection)生成读模型的视图。这个组合在策略引擎里非常强大。
但是,事件溯源也有代价。事件会不断累积,时间长了存储量会很大。我建议定期做快照(Snapshot),比如每1000个事件生成一个快照,重放时从最近的快照开始,而不是从头开始。
4.5 四种模式的关系与选择
这四种模式不是互斥的,而是可以组合使用的。我画了一张图来展示它们的关系:
在实际的策略引擎项目中,我通常这样组合:
- 规则变更通知:用发布-订阅,实时推送给所有订阅节点
- 用户行为分析:用事件流,保证顺序和可重放
- 规则配置管理:用CQRS,写模型保证一致性,读模型保证性能
- 审计与回滚:用事件溯源,记录每一次规则变更
我的建议:不要一开始就上全套。先从发布-订阅入手,等系统复杂度上来了,再逐步引入事件流、CQRS和事件溯源。我见过太多团队一上来就搞事件溯源,结果连基本的事件格式都没统一,最后项目烂尾。
好了,这一章就到这里。四种模式各有适用场景,关键是理解它们的核心思想,然后在实际项目中灵活组合。记住:模式是工具,不是教条。
公众号:蓝海资料掘金营,微信deep3321