Akka 如何对参与者集合执行查询

Akka 如何对参与者集合执行查询,akka,akka.net,Akka,Akka.net,我有一个actor系统,目前可以接受命令/消息。这些行动者的状态是持续的,阿卡。我们现在要为这个actor系统构建查询系统。基本上,我们的问题是,我们希望有一种方法来获得这些特定行为者的所有状态的汇总/列表。虽然我不是严格地赞同CQRS模式,但我认为这可能是一种很好的方式 我最初的想法是让一个参与者进行查询,作为其状态的一部分,保存正在进行“数据写入”的其他参与者的状态集合。为了做到这一点,这个参与者将订阅它感兴趣的参与者,这些参与者将只向查询参与者发送它们的状态,当它们经历某种状态变化时。这是

我有一个actor系统,目前可以接受命令/消息。这些行动者的状态是持续的,阿卡。我们现在要为这个actor系统构建查询系统。基本上,我们的问题是,我们希望有一种方法来获得这些特定行为者的所有状态的汇总/列表。虽然我不是严格地赞同CQRS模式,但我认为这可能是一种很好的方式


我最初的想法是让一个参与者进行查询,作为其状态的一部分,保存正在进行“数据写入”的其他参与者的状态集合。为了做到这一点,这个参与者将订阅它感兴趣的参与者,这些参与者将只向查询参与者发送它们的状态,当它们经历某种状态变化时。这是解决这个问题的方法吗?有更好的方法吗?

我对实现这种模式的建议是,在这里为您的参与者使用pub-sub和push-and-pull消息传递的组合

对于每个“聚合”,此参与者应该能够订阅来自要查询的单个子参与者的事件。每当子级的状态发生变化时,一条消息就会被推送到所有订阅的聚合中,并且每个聚合的状态都会自动更新

当一个新的aggegrate联机并需要检索它丢失的状态(在它存在之前)时,它应该能够从每个子级中提取当前状态并使用该状态来构建其当前状态,使用子级的增量更新来保持子级状态的聚合视图的一致性


这是我在这类工作中使用的模式,它在本地开箱即用地工作得很好。通过网络,您可能必须确保可交付性保证,这通常很容易做到。您可以在那里阅读更多关于如何实现的内容:

一些Akka.Persistence后端(即那些使用SQL的后端)也实现了一些称为Akka.Persistence.Query的东西。它允许您订阅生成的事件流,并将其用作语义源

如果您使用的是SQL日志,则需要Akka.Persistence.Query.SQL和Akka.Streams包。从那里,您可以为特定参与者创建实时(即不断更新)事件源,并将其用于您喜欢的任何操作,即打印它们:

使用(var system=ActorSystem.Create(“系统”))
使用(var materializer=system.materializer())
{
var querys=Sys.ReadJournalFor(SqlReadJournal.Identifier)
querys.eventsTypersistenceId(“”,0,long.MaxValue)
.Select(信封=>envelope.Event)
.RunForEach(e=>Console.WriteLine(e),物化器);
}

非常感谢!我有一个非常奇怪的行为:RunForEach方法是可等待的,当我等待它时,它会在控制台中打印出事件,但该方法没有完成,并创建了一种死锁!(我正在使用Postgresql作为我的数据库)您正在使用哪个查询
EventsTypersistenceId
是实时查询。这意味着,在达到最大sequenceNr之前,它不会完成。如果只想查询到目前为止存储的数据,请使用
CurrentEventsByPersistenceId
(或以
Current…
前缀开头的其他方法)。使用CurrentEventsByPersistenceId而不是EventsByPersistenceId是解决方案!非常感谢。