0

我们目前正在研究构建(Web)应用程序的新方法,想到的一种方法是 CQRS。我们对此仍有几个疑问:

如果我理解正确,这可能意味着拥有 2 个或更多域模型、一个核心域模型和一个用于 webapp 的读取模型。

这个核心域模型不是由 webapp 直接写入,而是由不同的服务写入。我们正在考虑使用 NServiceBus 来制作发布者/处理程序,以便 webapp 可以发布用户所做的更改。然后订阅者将处理消息并更新核心域模型和读取模型。

我们想要达到的目标:

用户 A 创建 10 个新对象,例如书籍。

消息订阅者有很多消息要处理,因此在更新域模型之前需要几分钟。

当用户 A 刷新页面时,他应该会看到他刚刚创建的 10 本书。

当用户 B 刷新页面时,他实际上并不需要查看这些项目。

这 10 个新对象最好存放在哪里?

将此数据与读取模型中的“旧”数据合并的最佳方法是什么?

假设用户 B 也确实需要查看这些新项目,那么存储这些数据的最佳方式是什么?

处理 2 个不同用户同时添加同一本书的最佳方法是什么? (所有数据都是一样的,除了书的描述。它仍然是同一本书:)

您可以通过什么方式处理对这 10 个尚未写入核心域模型并因此没有唯一 ID 的对象之一的更新?

4

1 回答 1

2

在我看来,CQRS 有很多不同的方面需要考虑。我从中得出的核心观点是用户操作(命令 -> 写入模型)和显示信息(查询 <- 读取模型)的分离。然后,我可以根据应用程序的要求,适当地挑选自然适合这种分离的其余架构模式。请记住,CQRS 并不意味着作为顶级架构,您应该从中挑选并仅在适当时使用。

从您的问题中,我觉得您的研究还没有走得太远,所以我推荐以下内容;初始 CQRS 文档Rinat Abdullin 的博客Jonathan Olivers 博客(阅读旧的东西)Rinat 的 CQRS 指南(虽然我还没有通读这个站点)

我保证通读CQRS 文档后,您将能够自己回答您的问题。

也许如果您告诉我们您希望使用的模式/技术,我可以提供更完整的答案。但是要开始您的第一个问题,它非常简单:

这 10 个新对象最好存放在哪里?

答案是从逻辑上讲,您将部分数据存储在写入和读取模型中;物理上,这可以存储在相同的数据存储中,也可以存储在不同的数据存储中,具体取决于您选择的技术和实现(例如 sql-server 数据库与 key-value no-sql 解决方案)。

例如,如果您选择使用事件溯源,那么您将在事件发生时存储在写入模型中。您的读取模型将存储非规范化、精心制作的数据,以便您的屏幕可以由您的读取模型的这些数据组成。但这与我所看到的模式保持一致。您的读取模型可以只存储使用查询服务规范化的数据,对实际数据库执行实际的 sql 查询。

编辑以下评论

我目前正在使用的系统不使用消息传递,尽管它使用事件。一切都在进行中。所以命令被处理;事件在同一个工作单元内被提出和处理。基本上,在适当的事件处理程序全部完成之前,命令处理程序不会完成。

当读取模型有更密集/复杂的更新时,我们仍在考虑进程外事件处理程序。但在这个阶段,不需要它,它使事情变得简单。

整个最终一致性方面只是模式附带的东西。对于“其他”用户来说,这永远不会成为问题,但对于刚刚提交然后刷新页面的用户来说,我可以看到这令人困惑,因为他们看不到他们刚刚提交的更新。就我个人而言,我不喜欢伪造更新的想法,因为这就像加倍努力。相反,我更喜欢重定向到确认页面的选项,从而为您的应用程序提供更多时间来处理消息。

我个人想进一步探索的是跟踪提交的命令和相关的进程外事件处理程序。刷新有消息尚未完成的页面的用户可能会收到不完整消息的通知。一旦消息完成处理,可以将通知“推送”到客户端。我会让这些通知变得微妙,以免分散用户的注意力或变得烦人。

于 2012-07-06T06:58:50.253 回答