在事件源中,我的发布者应用程序如何知道命令在许多订阅者中是成功的

时间:2017-07-10 20:08:01

标签: c# .net architecture rabbitmq event-sourcing

我计划构建多个应用程序,以了解有关如何在.net中使用事件源的更多信息。

到目前为止,这是我计划的架构。

Architecture

因此,网络应用1和网络应用2都可以创建用户,因此当网络应用1创建用户时,他将具有用户属性的命令msg发送给rabbitmq和事件处理程序1& 2使用所需的属性在相应的数据库中创建用户。

我不明白的是

f.ex

Web App 1上的访问者创建了一个帐户。

Web App 1将UserCreatedAccount消息发送到rabbitmq

两个事件处理程序都订阅消息并在相应的db

中创建用户

现在, Web应用程序1应该如何知道用户确实已经创建了?它应该假设一切正常并让用户通过吗?

我的架构计划缺少什么吗?

我不会从事件存储生成聚合,而只是将对象的当前状态存储在相应的数据库中。

2 个答案:

答案 0 :(得分:1)

  

我不会从事件存储生成聚合,而只是将对象的当前状态存储在相应的数据库中

首先,它听起来并不像您实际上正在实施事件采购。在事件采购中,它是事件存储,它是聚合状态的真实来源。

其次,您的图表显示了网络应用程序向rabbitmq发送命令。你打算在那里放置事件和命令吗?您是否正在尝试实施事件采购或命令源或两者兼而有之,目前尚不清楚。

这种犹豫不决在这里变得最明显:

  

Web App 1将UserCreatedAccount消息发送到rabbitmq

     

...

     

现在,Web应用程序1应该如何知道用户确实已经创建了?

关于事件的事情是它们是事实。如果UserCreatedAccount事件发生,那么它是不可否认的 - 这是事实。如果您的webapp不确定它是否属实,如果用户已创建或未创建,则它不得发出此类事件。

我认为你真正想做的事情(与图表更加一致)是webapp发出CreateUserAccount 命令。该命令由命令处理程序获取,如果成功,则实际发出UserCreatedAccount事件。由于命令可能会失败(事件不能 - 它们总是在过去),现在Web应用程序有合理的理由怀疑它是否成功。

现在解决方案。

Web应用程序可以监视命令处理程序发出的事件,以了解命令是否失败(相关ID将派上用场),但它也必须能够超时(或可能重试) 。这将变得复杂,并将取决于所需的延迟以及如何传达错误。

另一种方法是仅将Rabbitmq用于事件,但将命令直接从Web应用程序发送到命令处理程序。这样,您仍然可以正确实现事件源,但是从Web应用程序到命令处理程序的“正常”调用,以便您获得响应,无论它是成功还是失败。要为此添加位置透明度,我会考虑使用像akka.net这样的东西。

答案 1 :(得分:0)

  

在事件源中,我的发布者应用程序如何知道命令在许多订阅者中是成功的

事件采购中的常见答案是,当记录簿确认已成功更新时,发布者知道命令成功。

订阅者不一定立即看到这些更新(关键搜索词:最终一致性)。

因此,通常的设计是事件首先被写入持久事件存储,然后才会将它们放到队列中,然后将它们分发给订阅者。

因此,持久事件存储作为记录簿 - 系统中的单一事实来源,而订阅者则反映了这一事实。

(潜在的问题是邮件可能会丢失或重新订购,您需要一种从这些条件中恢复的方法)。

如果消息是命令,那么我们通常会有一个聚合,将命令转换为新事件以写入存储。如果消息是事件(FormSubmitted是一个事件,就像HttpRequestReceived那样),那么您不需要“聚合”,因此,只需要同步写入以确保更改已经变得持久。