我和我的团队一直在讨论使用 CQRS(命令查询职责分离)设计模式,我们仍在尝试评估使用它的利弊。根据:http://martinfowler.com/bliki/CQRS.html
我们还没有在该领域看到足够多的 CQRS 用途,但我们还没有确信我们了解它的优缺点
那么你们怎么看,什么时候需要使用 CQRS?
CQRS 不是包含整个应用程序的模式。
这是一个建立在领域驱动设计(DDD)之上的概念。而 DDD 的一个重要战略概念就是所谓的 Bounded Context。
在典型的应用程序中,有多个有界上下文,其中任何一个都可以按照有意义的方式实现。例如
用户管理 -> CRUD
发票 -> CRUD
保险单管理(核心领域)-> CQRS
...
这可能无法回答您的问题,但可能会更深入地了解该主题。老实说,如果不考虑项目的具体情况,我认为根本无法回答,即使这样,也很少有像明确的最佳实践这样的东西。
好吧,CQRL 批评者可能会说 CQRS 很复杂,这可能是真的。
当然,以 CQRS 样式开发一个简单的 CRUD 应用程序会增加开销,因此我会考虑仅在以下情况下使用 CQRS:
大型团队 - 如果您选择了 CQRS 架构,您可以轻松地在人员之间拆分开发任务。您的顶级人员可以处理域逻辑,将通常的东西留给技能较低的开发人员。困难的业务逻辑 - CQRS 迫使您避免混合领域逻辑和基础设施操作。可扩展性很重要——使用 CQRS,您可以获得出色的读写性能,命令处理可以在多个节点上横向扩展,并且由于查询是只读操作,因此可以对其进行优化以执行快速读取操作。
当您拥有复杂或困难的业务领域并且:
事件溯源;你想要一个测试逻辑的好方法
事件溯源;你想通过测试和推理来证明你的行为
您的域服务有多个客户端或消费者(不仅仅是单个 Web 服务器)
或者您有需要对公共数据采取行动的用户:
并且您想形式化您领域的数据合并概念
或者您想应用逻辑来合并事件
或者您有可扩展性要求:
您将模式应用为消除瓶颈的非规范化模式
你想水平而不是垂直缩放
或者您有性能问题(可扩展性的另一面):
例如,您需要将架构迁移到事件驱动的架构——CQRS 作为一种模式是一个很好的垫脚石。
或者你有一个物理分离的团队:
例如,您团队的一部分人在另一个国家
或者很难进行面对面的交流,因此您希望将读取模型与事物的写入端(sagas、域、CRUD)分离
过于复杂的不是 CQRS,而是计算机。
何时使用 CQRS 设计模式?
当难以从存储库中查询用户需要查看的所有数据时,可以使用 CQRS 架构模式。当 UX 设计创建跨越多个聚合类型和实例的数据视图时尤其如此。您的域越复杂,这就越容易发生。
当不适合在 UX 设计上妥协时,使用 CQRS 会尝试减轻与其他解决方案相关的问题,例如:
要求客户端使用多个存储库来检索所有聚合实例;或者
在各种存储库上设计专门的查找器,以使用单个查询来收集不连贯的数据。
总结一下:当难以从存储库中查询用户需要查看的数据时使用 CQRS,这往往会发生在您的域越复杂的情况下。
在现实世界的场景中,当您的前端/Web 服务客户端需要来自多个域的大量数据并且从数据库中检索这些数据需要很长时间时,CQRS 可能会很有用。
在这种情况下,您可能会考虑创建单独的读取模型,这将更快地开发并且可能具有更快的执行时间。
以下是使用 CQRS 的原因:
可扩展性(读大于写,因此每个的扩展要求不同,可以更好地解决) 灵活性(单独的读/写模型) 降低复杂性(将复杂性转移到单独的关注点) 专注于领域/业务 促进设计基于任务的直观 UI
以下是 CQRS Pattern
非常适合的一些场景:
需要高性能和独立可扩展性的大型项目。
在业务逻辑复杂的应用程序中。在这种情况下,您可以将读取与写入分开以使其更简单。
如果您想要并行开发,其中一个团队可以处理读取模型,而其他团队可以处理写入模型。
阅读此 Article 以了解有关 CQRS Pattern
的更多信息。
好吧,您的问题没有直接的答案,但我想给您一些实际示例,说明如何实现 CRQS,这可以帮助您弄清楚如何在您的应用程序中使用它,
1.Instagram
我们经常看到 Instagram 故事/卷轴等。这些商店是阅读密集型的,最好有一个单独的只读数据库来存储这些数据。外部世界只能处理那个特定的数据库来渲染你朋友时间线中的故事,这样做系统不需要打扰存储主要业务密集型信息的主数据库。
2.亚马逊
下订单时,订单服务会发出一个事件,该事件由其他服务订阅,其中一个可以更新非规范化只读数据库,而其他服务(比如说消息传递服务)可以简单地获取规范化信息,如 userId,从只读数据库订购等,并继续进行电子邮件处理以确认订单
如果您发现问题域不适合更通用的架构,或者您正在尝试域驱动设计,我建议您尝试一下 CQRS。
这是一个强大的模式,可以让您很好地了解问题域并解决一些技术和基础设施挑战。但值得牢记的是,它会带来价格,并且由于与其他架构的概念差异,它需要心智模型的转变。
在以下情况下使用它:
拥有复杂的域,需要通过命令了解域
https://docs.microsoft.com/en-us/azure/architecture/patterns/cqrs#when-to-use-this-pattern
关于实现 CQRS,我喜欢当您的前端/Web 服务客户端需要来自多个域的大量数据时分离读取模型的想法,我想尝试一下。我想尝试它的主要原因是开发和执行过程中的“缓慢”问题;特别是在处理大型数据集或“大数据”时。我正在研究可用于降低复杂性、增加混合架构的可扩展性、弹性和灵活性的所有各种选项。