akka 如何在CQRS模式中获得集合的状态?

8hhllhi2  于 2022-11-05  发布在  其他
关注(0)|答案(4)|浏览(184)

根据Martin Fowler和 Microsoft CQRS Journey 的文章,CQRS是一种应用于BC的模式,而不是整个系统的架构。我对如何从CQRS中的任何外部内容获得聚合状态感到困惑。

聚合是否应具有命令Get以在写入模型中返回其状态,或在读取模型中具有相应的查询?

这是Akka Platform Guide中的购物车服务示例。
ShoppingCart是一个聚合,它有三个命令:AddItemCheckoutGet,在Get的命令处理器中,它将购物车摘要回复给命令发送方,这样每个聚合体都有一个命令Get,以写模式返回它的状态。
但我假设Get确切地说是一个查询,而不是一个命令。因为在CQRS模式中,命令更改聚合的状态并触发事件,但什么也不返回。另一方面,查询返回聚合的当前状态的副本,但什么也不更改。所有命令都存在于写入模型中,所有查询都存在于读取模型中。如果我想获取状态,我不应该发出写模型的命令,而应该发出读模型的查询,最终的一致性是通过写模型到读模型的事件Map来维持的。
因此,ShoppingCartGet应该被移动到读取模型中。任何外部想要获得ShoppingCart的状态,它应该发送查询GetShoppingCart,并最终获得回复Summary。但是这样做,状态可能是陈旧的。它是否会出现一致性问题?

哪种设计是必要的和更好的?

Get放在read模型中会有一致性的风险,否则放在write模型中会产生语义歧义。这是我的困惑。

  • 谢谢-谢谢
uxh89sit

uxh89sit1#

把Get放在read模型中会有一致性的风险,把它放在write模型中会有语义的歧义,这是我的困惑。
第一,现实检查;从这些像素出现在屏幕上到你的眼睛看到它们之间的时间大约是一纳秒。所以你现在看到的答案至少有那么老了。在网络上跳跃需要多少时间,至少一毫秒。
换句话说,查询响应已经过时了,确保它仍然是聚合的“当前”状态的准确表示的唯一方法是锁定所有命令,直到您完成对它的查看。
如果你必须这么做,你 * 可以 * 这么做,但是这是有代价的。锁定是合适的选择的情况,据我所知,是罕见的。但是如果你需要它,你就需要它。注意:在这种情况下,你可能不得不给予CQRS。
更灵活的框架是查询处理程序返回的不是聚集“现在”的表示,而是聚集在(最近)过去某个特定点的表示。
因此,我在12:02发送了一些查询,得到的是一份报告副本,该副本是根据12:00时聚合状态的副本准备的。作为客户,我知道这一点,因为在报告的顶部有一个用大字体写的声明,上面写着“此报告是在12:00准备的”。
这会引出许多有趣的问题,因为现在您讨论的是时间和SLO(最新的报告是否足够好,或者我们是否需要更新的报告?与检查更新版本相比,我们可以缓存报告多长时间?我们是否愿意牺牲一些额外的响应延迟来获取更新版本?如果没有可用的报告更新版本,系统中应该发生什么情况?)
我不确定是否应该在写入模型中放置Get命令以返回聚合状态。我更喜欢在读取模型中添加查询Get
我就是这样做的--查询处理程序加载一个“读模型”的副本,并从中收集信息,而“写模型”则不会被加载。

hvvq6cgz

hvvq6cgz2#

我不熟悉 akka ,但我是这么看的:
最终的一致性不是在写入和读取端之间,而是在分布式系统中的复制(投影、读取模型、索引等)之间。
在写模型中使用Get支持没有什么意义,因为读和写不必彼此一致。它们根本不必使用相同的概念。读模型甚至可以是多个聚合的投影(理论上)。然而,有时候,在写模型中使用更简单的 transient 投影是有用的,但它们只应在写操作期间使用,而不应暴露给纯读。
记住,写模型的唯一目的是投射足够的状态,以便能够处理和验证命令,并产生事件。
我不确定我回答了你的问题,但这是我如何看待一致性和读/写模型等。无论如何,欢迎来到堆栈溢出!

e3bfsja2

e3bfsja23#

我得到了团队的回复。
出于多种原因,它们在写入端演示了Get命令:
1.显示了处理不产生事件的命令的功能。
1.举例说明有时需要一致性,而在单个聚合范围内这是可能的。
原来如此。

xt0899hw

xt0899hw4#

当您对Akka框架和CQRS模式感兴趣时,您应该检查Akka框架的另一部分Akka Projections
正如你提到的,在Akka中实现CQRS的命令部分非常有意义,但是使用命令(如“Get”)的查询部分很笨拙,另外,对于任何其他查询表单,你可以只为ActorId获得有意义的信息,而你必须做一些效率很低的事情。
Akka Projection可以使用开箱即用的JDBC数据源、Apache Cassandra等,为您提供更大的可伸缩性,同时也为您提供了更大的灵活性,您可以如何塑造您的查询,最终的一致性问题将存在,但这是根据用例来判断的。
我在我的博客中使用了同样的原理,如果你想看看它是否完成了,你可以在那里查看。作为奖励,你会看到我用Elasticsearch实现了Akka Projection,这是Akka Projections,blog1blog2没有的。

相关问题