什么时候使用 CQRS 设计模式?

我的团队和我一直在讨论使用 CQRS (命令查询责任分离)设计模式,我们仍在尝试评估使用它的利弊。根据: http://martinfowler.com/bliki/CQRS.html

我们还没有看到足够的 CQRS 在该领域的应用,还没有信心 我们了解它的利弊

那么你们怎么看,什么时候需要使用 CQRS 来解决问题呢?

45361 次浏览

CQRL 的批评者可能会说 CQRS 是复杂的,这可能是真的。

当然,以 CQRS 风格开发一个简单的 CRUD 应用程序会增加开销,所以我会考虑只在以下情况下使用 CQRS:

  1. 大团队 -如果您选择了 CQRS 体系结构,您可以很容易地在人员之间分配开发任务。你的顶级人员可以处理领域逻辑,把一般的东西留给技术不熟练的开发人员。
  2. 困难的业务逻辑 -CQRS 迫使您避免混合域逻辑和基础结构操作。
  3. 可伸缩性问题 -使用 CQRS,您可以实现很好的读写性能,命令处理可以在多个节点上扩展,并且由于查询是只读操作,因此可以优化它们以执行快速读操作。

CQRS 不是一个包含整个应用程序的模式。

这是一个基于领域驱动设计(DDD)的概念。DDD 的一个重要战略概念就是所谓的 有界语境

在一个典型的应用程序中,存在多个有界上下文,其中任何一个都可以按照有意义的方式实现。比如说

  • 用户管理-> CRUD
  • 发票-> CRUD
  • 保险政策管理(核心领域)-> CQRS
  • ...

这可能不会回答你的问题,但它可能会提供一个更多的洞察力的主题。老实说,如果不考虑项目的具体情况,我认为根本无法回答这个问题,即使是这样,也很少有像确定的 最佳实践这样的东西。

当你有一个复杂或者困难的业务领域,并且:

  • 事件源; 您需要一种很好的测试逻辑的方法
  • 你想通过测试和推理来证明你的行为
  • 您的域服务有多个客户端或使用者(而不仅仅是单个 Web 服务器)

或者,您有需要根据公共数据采取行动的用户:

  • 并且您希望将域的数据合并概念形式化
  • 或者希望为合并事件应用逻辑

或者你有可伸缩性需求:

  • 您应用该模式作为消除瓶颈的反规范化模式
  • 你想要水平而不是垂直扩展

或者你有性能问题(可伸缩性的另一面) :

  • 例如,您需要将您的体系结构迁移到事件驱动的体系结构-将 CQRS 作为模式是一个很好的踏脚石。

或者,你的团队在物理上是不相干的:

  • 你的部分队员在另一个国家
  • 或者很难获得面对面的通信,因此您希望将读模型与事物的写端(传说、域、 CRUD)解耦

过于复杂的不是 CQRS,而是计算机。

什么时候使用 CQRS 设计模式?

当难以从存储库查询用户需要查看的所有数据时,可以使用 CQRS 体系结构模式。当用户体验设计创建跨多个聚合类型和实例的数据视图时尤其如此。你的领域越复杂,这种情况就越容易发生。

当不适合在用户体验设计上妥协时,使用 CQRS 试图减轻与其他解决方案相关的问题,例如:

  • 要求客户端使用多个存储库来检索所有聚合实例; 或者
  • 在各种存储库上设计专门的查找程序,使用单个查询收集脱节的数据。

总结: 当用户需要查看的存储库数据很难查询时,使用 CQRS,这种情况往往发生在域越复杂的时候。

使用 CQRS 的原因如下:

  1. 可伸缩性(读取超过写入,因此每种方法的伸缩性要求不同,可以更好地解决)
  2. 灵活性(单独的读/写模型)
  3. 简化复杂性(将复杂性转换为单独的关注点)
  4. 专注于领域/业务
  5. 便于设计直观的基于任务的 UI

在现实场景中,当前端/Web 服务客户端需要来自多个域的大量数据,而从数据库中检索这些数据需要很长时间时,CQRS 可能非常有用。

在这种情况下,您可以考虑创建单独的读模型,这样开发起来会更快,执行时间也会更快。

关于实现 CQRS,我喜欢在前端/Web 服务客户端需要来自多个域的大量数据时分离读模型的想法,我想尝试一下。我想尝试它的主要原因是由于开发和执行过程中的“缓慢”问题,特别是当涉及到处理大数据集或“大数据”时。我正在研究所有可用于降低复杂性、为混合体系结构增加可伸缩性、弹性和灵活性的选项。

如果你发现问题域不适合更通用的架构,或者你正在尝试领域驱动设计,我建议你试试 CQRS。

它是一种强大的模式,可以让您很好地了解问题领域,并解决一些技术和基础设施方面的挑战。但是值得记住的是,它将带来代价,并且由于与其他体系结构在概念上的差异,它将需要心理模型的转变。

简介

在以下情况下使用:

  1. 有一个复杂的域,需要通过命令来理解域
  2. 读和写的应用程序负载不同
  3. 希望在任何时间点缩放读操作

Https://learn.microsoft.com/en-us/azure/architecture/patterns/cqrs#when-to-use-this-pattern

下面是 CQRS Pattern完全适合的一些场景:

  • 需要高性能且独立的大型项目 需要可伸缩性。
  • 在业务逻辑复杂的应用程序中, 你可以把读和写分开,这样更简单。
  • 如果您想要并行开发,其中一个团队可以进行阅读 模型和其他团队在写模型方面的工作。

阅读此 文章了解更多关于 CQRS Pattern的信息。

你的问题没有直接的答案但我想给你一些 如何实施 CRQS 的真实例子可以帮助你弄清楚如何在你的应用程序中使用它,

1. Instagram

我们经常看到 Instagram 上的故事/视频等等。这些存储是读密集型的,对于这些数据,最好有一个单独的只读数据库。外部世界只能处理那个特定的数据库,以便在朋友的时间线中呈现故事,这样系统就不需要打扰存储主要业务密集型信息的主数据库。

2. 亚马逊

当一个订单被下达时,订单服务发出一个事件,这个事件被其他服务订阅,这些服务可以更新非规范化的只读数据库,其他服务(比如消息服务)可以简单地从只读数据库中获取规范化的信息,比如用户 ID、订单等等,然后进行电子邮件处理以确认订单

每个人都解释了为什么需要使用 CQRS,但是让我们来谈谈 没有使用它的原因:

因此,CQRS 应用的主要特点之一就是数据为 最终一致性。这意味着由于更新数据的同步进程,查询检索的数据可能并不总是最新的数据。在处理这些请求时,它可能会导致命令和查询之间出现一定的延迟。如果你要使用 CQRS,你必须意识到这一点,在你的业务需要有很强的一致性的情况下,你应该 没有使用 CQRS。(银行申请)

enter image description here