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: 事件匹配

    深入讲解 whenwhenAny 的区别,以及如何精确匹配特定事件类型。

  • >> 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 和事件建模能力,否则只会越搞越乱

原始标题:CQRS and Event Sourcing Resources

« 上一篇: Baeldung周报19