事件 – 用于CQRS事件发布设置的NServiceBus

我们目前正在建立一个基于CQRS的项目.每个Web项目实例都运行NEventStore,但是它们共享相同的EventStore持久性(底层数据库).

现在我们要发布存储的事件:不仅是我们的ReadModel(每个Web项目实例一个),还有其他事件消费者(例如遗留应用程序,它们也需要以某种方式通知我们的系统,以及许多更多).

因此,我们有x个事件使用者(=事件处理程序)和y事件发布者,但只有一个事件的“真实来源”(底层的EventStore数据库).

问题1:现在是通过发布/订阅连接这些系统的最佳做法吗?

我们考虑过通过NServiceBus从EventStore发布事件.所有消费者都应该订阅他们需要的活动类型 – 因此每个消费者也需要在多个发布商订阅 – Q2:这是否可能?我们已经读过您无法在多个位置订阅同一事件,请参阅:David Boike“在QueueName @ WebServer1上订阅Message1后,您将无法订阅来自QueueName @ WebServer2的Message1.”

其他开放性问题:
问题3:如何检测消费者是否已永远关闭(如果未成功取消订阅总线). – >队列运行满了吗?!如何将它与仅丢失网络连接的情况区分开来?

问题4:如果订阅服务和EventStore之间的连接不可靠并且失败,会发生什么?消费者在订阅服务上成功注册,但EventStore不知道新订阅,也不提供消息……

问题5:一般情况下:NServiceBus如何处理队列?当消费者长时间无法访问(例如几天)时会发生什么?

最佳答案 Q1:这取决于您订阅邮件的方式. NServiceBus的构建是存在业务服务(有界上下文),它们无法共享数据.但是在CQRS中,您会发送包含大量数据的胖事件,这些事件将被发布,以便订阅者可以将信息存储在其读取模型中.例如,在用户界面中使用该读取模型.通过普通用户界面或通过复合用户界面(从多个业务服务收集信息).所以这取决于你在寻找什么.

Q2:可以订阅多个事件.但是,该事件只有一个逻辑发布者.因此,“CustomerWasBilled”事件不能来自ComponentA和ComponentB.但是,您可以订阅许多不同的活动,每个发布者当然可以拥有许多不同的订阅者.

[Udi]给定的发布者可以跨多个服务器扩展,NServiceBus将为您处理 – 无需订阅每台机器.

问题3:我认为这是纯粹的管理.如果它应该保持在线并接收消息,队列将填满.如果它应永久地向下/离线并且不处理消息,那么在组件被拆除后你会非常快地知道.但我强烈建议记录哪些订阅者和发布者彼此连接以及如果更改消息或组件会发生什么.

[Udi]如果它是有序关闭,那么它应该包括取消订阅.如果是临时崩溃,那么您可以通过标准监视(WMI)检测到它.为了保护您的队列不被填满,您可以使用TimeToBeReceived属性定义何时应丢弃消息.

Q4:这是在NServiceBus中处理的.它将订阅存储在数据存储区中,该数据存储区可以是SQL Server,RavenDB&在记忆中.但它也会将订阅保留在内存中,并定期检查是否添加了新订阅.不应该是NServiceBus的问题.

问题5:MSMQ本身就是可靠的.当然,如果整个服务器崩溃并且所有消息都在HD上,那就是问题.如果组件在较长时间内无法访问,则可能会发生这种情况,这取决于SLA.您可以监视传入队列或错误队列中的消息计数.不要忘记DeadLetterQueue.但NServiceBus还允许您监视处理消息所需的时间.

当组件长时间(例如几天)无法访问时,业务应该决定做什么.如果重要消息得到处理,请引入群集等.

希望这可以帮助

点赞