大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
事件驱动架构
事件驱动架构(EDA) 把系统协作重心从「我调你的 API」转为「我发布发生了什么,你自行反应」。核心收益是 解耦与时间上的弹性;代价是 最终一致与可观测性要求更高。
学习目标
- 区分 Event Notification 与 Event-Carried State Transfer
- 理解 Event Sourcing 与 CQRS 的关系(浅尝)
- 串联 kafka-spring 发布订阅实践
两种事件风格
| 风格 | 内容 | 消费者行为 |
|---|---|---|
| Event Notification | OrderId=123 created | 收到后再 调 API 查详情 |
| Event-Carried State Transfer | 订单快照字段全在 payload | 本地投影,少调下游 |
Notification 消息小、但增加同步调用;Carried State 利于自治,但 payload 变大、 schema 演进要规范。
典型 EDA 拓扑
┌─────────────┐ OrderCreated ┌──────────────┐
│ order-svc │ ────────────────────► │ Kafka Topic │
│ (写模型) │ └──────┬───────┘
└─────────────┘ │
┌────────────────────────┼────────────────────────┐
▼ ▼ ▼
[inventory] [notification] [read-model]
扣减库存 发邮件 更新 ES/Redis
写路径仍可在 order-svc 用 sb-transaction;跨服务 用 Outbox 或事务消息避免「库写了、消息没发」。
Outbox 模式(直觉)
同一 DB 事务:
INSERT orders ...
INSERT outbox_events (payload, status=pending)
─────────────────────────────────────────────
独立 Relay 进程:扫 outbox → publish Kafka → mark sent
保证 至少发一次;Consumer 端需 ip-idempotency。
与同步微服务对比
- Feign 链式调用:调试简单,故障传播快(sc-feign)
- 事件链:新增订阅者不改 Producer,适合 多团队并行
RabbitMQ fanout 适合 少量订阅、任务型;Kafka 适合 高吞吐、可重放、流处理(kafka-streams)。
何时不上 EDA
- 强一致跨聚合根、步骤少 → 同步或 Saga 更直接
- 团队无 MQ 运维能力 → 先 ip-sync-async 评估
练习
- 设计 OrderPaid 事件:选 Notification 还是 Carried State,写理由
- 画 Outbox 与 Kafka 的时序图
- 对照 ip-cqrs 说明读模型如何更新
小结
EDA = 用事件解耦写与读、生产与消费。 下一课:Saga 与分布式事务。