Akka 如何在CQRS模式中获取聚合的状态?

Akka 如何在CQRS模式中获取聚合的状态?,akka,cqrs,Akka,Cqrs,根据Martin Fowler和Microsoft CQRS Travel的文章,CQRS是一种应用于BC的模式,而不是整个系统的体系结构。我对如何从CQR中的任何外部获取聚合状态感到困惑 聚合应该使用命令Get在写模型中返回其状态,还是在读模型中返回相应的查询? 这是中国购物车服务的一个例子 ShoppingCart是一个聚合,它有三个命令:AddItem、Checkout和Get。在Get的命令处理程序中,它将购物车摘要回复给命令发送者。这样,每个聚合都有一个命令Get,用于返回其在写模型中

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

聚合应该使用命令
Get
在写模型中返回其状态,还是在读模型中返回相应的查询?

这是中国购物车服务的一个例子

ShoppingCart
是一个聚合,它有三个命令:
AddItem
Checkout
Get
。在
Get
的命令处理程序中,它将购物车摘要回复给命令发送者。这样,每个聚合都有一个命令
Get
,用于返回其在写模型中的状态

但是我认为
Get
确实是一个查询,而不是一个命令。因为在CQRS模式中,该命令更改聚合的状态并触发事件,但不返回任何内容。另一方面,查询返回聚合当前状态的副本,但不更改任何内容。所有命令都存在于写模型中,所有查询都存在于读模型中。若我想获取状态,我不应该发送一个命令来编写模型,而应该发送一个查询来读取模型。通过从写模型到读模型的事件投影来维持最终的一致性

因此,应该将
ShoppingCart
Get
移动到读取模型中。任何外部想要获取
ShoppingCart
的状态的东西,都应该向
ShoppingCart
发送查询
get
,并最终获取回复
摘要
。但这样的话,国家可能已经过时了。它的一致性会有问题吗

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

Get
放在读取模型中会有一致性风险,而将其放在写入模型中则会有语义歧义。这是我的困惑

谢谢

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

第一,现实核查;从这些像素出现在屏幕上到眼睛看到它们之间的时间大约为一纳秒。所以你看到的答案至少有那么古老。需要多少时间,至少一毫秒?在网络上跳跃

换句话说,查询响应已经很旧了。确保它仍然是聚合当前状态的准确表示的唯一方法是锁定所有命令,直到查看完为止

如果必须的话,你可以这样做,但这是有代价的。从我所知道的情况来看,锁定是正确选择的情况很少。但如果你需要它,你就需要它。注意:在这种情况下,您可能不得不放弃CQR


更灵活的框架是,查询处理程序返回的不是“现在”聚合的表示,而是(最近)过去某个特定点的聚合的表示

所以我在12:02发送了一些查询,我得到的是一份报告的副本,该报告是根据12:00聚合状态的副本准备的。而我,客户,知道这一点,因为在报告的顶部有一封友好的大信件,上面写着“这份报告是在12:00准备的”


这会引发很多有趣的问题,因为现在你谈论的是时间和SLO(最新报告是否足够好,或者我们是否需要更新的报告?与检查更新版本相比,我们可以缓存报告多长时间?我们是否愿意牺牲一些额外的响应延迟来获得更新版本?当没有更新版本的报告可用时,系统中会发生什么情况?)


我不确定它是否应该在写模型中放入命令Get来返回聚合状态。我更喜欢在读模型中添加查询Get


我就是这样做的-查询处理程序加载“读取模型”的副本并从中收集信息。“写入模型”不会加载。

我不熟悉Akka,但以下是我的看法:

最终的一致性不是写端和读端之间的一致性,而是分布式系统中复制之间的一致性(投影、读取模型、索引等)

在写模型中获得支持没有什么意义,因为读和写不必彼此一致。它们根本不必使用相同的概念。读模型甚至可以是多个聚合的投影(理论上)。但是,有时在写模型中使用更简单的瞬态投影是有用的,但它们只应在写操作期间使用,而不应公开用于纯读取

请记住,编写模型的唯一目的是投射足够的状态,以便能够处理和验证命令,并生成事件。就是这样


我不确定我是否回答了你的问题,但这就是我如何看待一致性和读/写模型等。无论如何,欢迎来到Stack Overflow!

我得到了团队的答复

它们在写端演示了
Get
命令,原因有多种:

  • 显示处理不产生事件的命令的功能
  • 举例说明有时需要一致性,这在单个聚合范围内是可能的

  • 就是这样。

    谢谢。我同意你的观点,在CQRS模式中查询的结果总是过时的。但我不确定是否应该将命令
    Get
    放入write模型以返回聚合状态。我更喜欢将query
    Get
    添加到read模型中。谢谢。我的困惑是关于CQRS模式,而不是Akka本身的例子。在CQ中RS模式,写端实现所有域逻辑,读端提供材料查询。写端维护聚合状态,然后将事件持久化并将事件投影到读端。读端使用投影事件并更新