【问题标题】:NEventStore: Sagas, Commands and not Losing ThemNEventStore:Sagas、命令和不丢失它们
【发布时间】:2015-02-16 23:12:16
【问题描述】:

NEventStore:5.1
简单设置:WebApp (Asp.NET 4.5) == 命令端

我正在寻找不丢失命令的“正确”方法,着眼于 sagas/process-managers,这可能会无休止地等待一个实际上从未发生过的命令产生的事件处理。

旧:调度员

我最初使用了同步命令,但关注 sagas/process-managers 我认为先存储它们然后通过 SyncDispatcher(或 AsyncDispatcher)获取它们会更安全。否则,我担心的是,如果 saga 尝试发送命令并且由于 app-crash/powerloss/... 导致命令未完成,它将丢失并且 noone会知道

所以我创建了一个 command-stream 并将每个命令附加到其中。 IsDispatched 显示,如果该命令已被处理。
那行得通。

PollingClient 和 Command-Stream

现在调度程序已经过时,我切换到 PollingClient。我丢失的是Dispatched 信息。

出现了启动问题:
我天真地从当前最新的检查点开始轮询以后,但是当应用程序重新启动时,可能会存储命令但之前没有执行崩溃并因此丢失(实际上发生了)。

我刚刚遇到了想法
将命令的基本结果作为(非域)事件存储在另一个流中
此流将包含 CommandSucceededCommandFailed 事件。
每当应用程序启动时,最新的 command-id 或 command-checkpoint-number 就会被提取出来,用于在该命令之后立即加载命令...

问题

  • 我担心同步命令处理会导致丢失 saga 生成的命令的危险吗?如果是,为什么?
  • 这通常是个好主意吗:一个大的命令流?
  • 这通常是个好主意吗:将通用命令结果事件存储在流中?

【问题讨论】:

    标签: command cqrs saga neventstore


    【解决方案1】:

    你可以:

    1. 将您的命令存储在命令队列中|持久性日志
    2. 在 NEventStore 上使用命令 ID (guid) 作为提交 ID
    3. 在命令处理程序中将您的命令标记为已执行 |管道挂钩 |轮询客户端

    NEventStore 在相同的 AggregateId (streamid) + CommitId 上为您提供幂等性,因此如果您的应用在命令被标记为已处理之前崩溃并重播命令,NES 会自动丢弃生成的提交。

    【讨论】:

    • 谢谢,如果我遵循“一个命令 - 一个聚合被更改”的原则,那将起作用。不幸的是,我不得不承认:我没有。所以多个提交将共享相同的提交 ID(= 命令 ID) - 因此只有第一个提交会获胜......
    • 嗯..请尝试。幂等性在流级别处理,因此即使每个提交 ID 处理多个聚合也应该有效。在命令端拥有所有聚合 id 很重要。
    • 哦“每 stream -level”...这很好...对我的情况特别:我仍然有一个问题,因为我存储了多个聚合变量 ("同一事物的视图”,即 1 个流中的“OrderableResource”和“StoreableResource”)在一个聚合流中,但我没有在一次提交中提交所有内容,但我确实传递了命令 ID知道最初是什么命令导致了该事件......但这可以通过使用此命令持久性“轻松”修复。
    • @初始问题:对问题 2 和 3 有意见吗? (我基本上也使用 NEventStore 作为消息总线)
    • @Warappa 你不应该使用 NEventStore 作为消息总线。使用具有持久性支持的真实总线
    【解决方案2】:

    Afaik NEventStore 旨在作为事件源的存储,即将域对象存储为事件流。命令和传奇与它无关。您的服务总线应该负责持久性和传奇管理。

    就个人而言,我将事件存储简单地视为存储库详细信息。应用程序服务(命令处理程序)将在生成的事件被持久化后分派它们。

    如果应用程序崩溃并且服务总线是持久的(不是内存总线),那么事件/命令将再次自动处理,因为服务总线应该检测消息是否未成功处理。当然,出于这个原因,您的消息处理程序应该是幂等的。

    【讨论】:

    • 我目前使用 NEventStore 作为普通事件存储来存储命令消息。我在某处听说过这个想法,到目前为止对我来说似乎很好。通过还存储命令,我可以选择在我的开发系统上实际重播它们。通过提到具有命令结果流的想法,我还可以获得失败命令的错误原因(异常消息,...)。因此,如果我在重播时忽略命令并且有办法了解最后执行的命令,我有一个消息队列,我可以在最后执行的命令之后赶上(我知道由于命令结果流)
    • 当 saga 以与聚合相同的方式实现时,即将其状态保存到事件流中,使用相同的持久化框架不是很实用吗?我以为bucketId 就是为此而生的?
    猜你喜欢
    • 2021-11-10
    • 2016-12-16
    • 2013-10-22
    • 1970-01-01
    • 2021-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多