我计划构建多个应用程序,以了解有关如何在.net中使用事件源的更多信息。
到目前为止,这是我计划的架构。
因此,网络应用1和网络应用2都可以创建用户,因此当网络应用1创建用户时,他将具有用户属性的命令msg发送给rabbitmq和事件处理程序1& 2使用所需的属性在相应的数据库中创建用户。
我不明白的是
f.ex
Web App 1上的访问者创建了一个帐户。
Web App 1将UserCreatedAccount消息发送到rabbitmq
两个事件处理程序都订阅消息并在相应的db
中创建用户现在, Web应用程序1应该如何知道用户确实已经创建了?它应该假设一切正常并让用户通过吗?
我的架构计划缺少什么吗?
我不会从事件存储生成聚合,而只是将对象的当前状态存储在相应的数据库中。
答案 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那样),那么您不需要“聚合”,因此,只需要同步写入以确保更改已经变得持久。