1. 文章
1.1. Martin Fowler 撰写
>> CQRS | Martin Fowler
Martin Fowler 对 CQRS(Command Query Responsibility Segregation,命令查询职责分离)的权威解读。他指出,CQRS 的核心思想是将写操作(命令)与读操作(查询)彻底分离,使用不同的模型来处理。这种分离在复杂业务场景下能显著提升系统可维护性和扩展性。
✅ 适合读模型和写模型差异较大的系统
❌ 过度设计风险高,小项目慎用
>> 事件溯源 | Martin Fowler
事件溯源(Event Sourcing)是一种将状态变更记录为一系列不可变事件的架构模式。Fowler 强调,通过事件重建状态,可以实现完整的审计日志、时态查询(如“账户三天前的余额”),并天然支持事件驱动架构。
⚠️ 踩坑提示:事件结构一旦发布就不能随意修改,需提前设计好版本兼容策略。
1.2. Greg Young 撰写
Greg Young 是 CQRS 和事件溯源领域的奠基人之一,他的文章兼具理论深度与实战指导。
>> 创建流的代价
讨论在 EventStore 中创建 stream 的性能开销。虽然创建 stream 成本极低,但滥用仍可能导致元数据膨胀。建议按业务实体(如用户、订单)划分 stream,避免过度细分。
>> Projections vs RxJS vs 其他
对比了 EventStore 中的 Projections 机制与 RxJS 等响应式编程模型的异同。Projections 更适合在服务端进行事件流的持续转换和聚合,而 RxJS 更适用于客户端或轻量级处理。
关于 Projections 的系列文章:
>> Projections 1: 理论基础
介绍 Projections 的基本概念:从事件流中提取信息并生成新的视图或流。这是实现读写模型同步的关键机制。
>> Projections 2: 一个简单的 SEP 投影
SEP(Simple Event Processor)示例展示如何用 JavaScript 编写一个投影,将
UserCreated
事件映射为用户列表视图。fromStream('users') .when({ UserCreated: function(state, event) { emit('user-list', 'UserAdded', { name: event.body.name, id: event.body.id }); } });
>> Projections 3: 使用状态
展示如何在投影中维护状态,实现聚合计算,比如统计某个流中事件的数量。
>> Projections (中场休息)
回顾前几篇内容,并澄清一些常见误解,比如“Projections 是否会影响写入性能?”——答案是不会,它是异步执行的。
>> Projections 4: 事件匹配
深入讲解
when
与whenAny
的区别,以及如何精确匹配特定事件类型。>> Projections 5: 索引机制
如何利用投影构建索引流,加速查询。例如,根据用户邮箱快速定位其事件流。
>> Projections 6: 一个索引用例
实战案例:为大量用户构建邮箱到用户ID的映射索引,解决全局查询性能问题。
>> Projections 7: 多流处理
处理跨多个 stream 的事件,实现跨领域聚合,比如“所有订单中的最高金额用户”。
>> Projections 8: 内部索引
探讨 EventStore 内部如何优化投影的执行效率,包括自动索引和状态快照机制。
1.3. 其他作者
>> 最终一致性 – 再谈 | Werner Vogels
Amazon CTO Werner Vogels 经典之作,阐述分布式系统中“最终一致性”的必要性与权衡。对于理解 CQRS 中读模型延迟更新有重要启发。
>> 命令查询分离 | Wikipedia
CQRS 的思想源头来自 Bertrand Meyer 的 Command-Query Separation(CQS)原则:一个方法要么是命令(改变状态),要么是查询(返回数据),不能两者兼有。
>> CQRS 入门指南
CodeProject 上的通俗教程,适合快速了解 CQRS 架构的基本组成:命令处理器、事件总线、事件存储、查询模型等。
>> 领域驱动设计、CQRS 与事件溯源入门
将 DDD、CQRS 和 Event Sourcing 结合讲解,强调聚合根、领域事件等核心概念在实际架构中的落地方式。
>> CQRS 官方站点
汇集了大量 CQRS 相关文章、模式说明和社区讨论,是持续学习的好去处。
>> 何时应避免使用 CQRS
Udi Dahan 提醒我们:CQRS 并非银弹。在团队缺乏领域建模经验、系统复杂度不高时,引入 CQRS 只会增加维护成本。
>> 什么时候不该用 CQRS?
进一步补充使用 CQRS 的前提条件:需要明确的业务动因,比如高性能写入、复杂查询、审计需求等。
>> DDD/ES 缺失的指导
探讨在实际项目中落地 DDD 和事件溯源时常见的盲区,如事件命名规范、版本管理、测试策略等。
2. 演讲与视频
>> 使用微服务架构开发应用 – Chris Richardson (完整版)
Chris Richardson 系统讲解了如何结合微服务、事件溯源和 CQRS 构建可扩展系统。重点介绍了事件驱动通信、Saga 模式处理分布式事务等关键技术。
>> hack.summit() – Chris Richardson – 2014年12月 (+ 幻灯片)
更精炼的演讲版本,配套幻灯片详细展示了基于 Docker 部署事件溯源微服务的完整流程。
>> Greg Young – CQRS 与事件溯源 – Code on the Beach 2014
Greg Young 亲自讲解 CQRS 的本质:不是框架,而是一种应对复杂性的思维方式。他用简单例子拆解常见误区,比如“CQRS 就是加了个消息队列”。
>> Greg Young 的 CQRS 课程 第8讲
这是一套完整课程的一部分,深入探讨事件存储设计、快照机制、投影重构等高级话题。适合想深入底层原理的开发者。
📌 总结建议:
- ✅ CQRS + Event Sourcing 适合高并发、强审计、复杂业务逻辑的系统
- ❌ 初创项目或 CRUD 系统不要盲目上车,容易掉进分布式陷阱
- ⚠️ 团队必须具备一定的 DDD 和事件建模能力,否则只会越搞越乱