我们目前正在建立一个基于CQRS的项目。每个Web项目实例都运行NEventStore,但是所有实例都共享相同的EventStore持久性(底层数据库)。
现在,我们希望发布存储的事件:不仅发布到我们的ReadModel(每个Web项目实例一个),还发布到其他事件消费者(例如,遗留应用程序,它们也需要以某种方式了解我们系统中的事件,等等)。
因此,我们有x个事件使用者(=事件处理程序)和y个事件发布者,但只有一个事件的"真正来源"(底层EventStore数据库)。
Q1:现在是否有通过发布/订阅连接这些系统的最佳实践?
我们考虑过通过NServiceBus从EventStore发布事件。所有消费者都应该订阅他们需要的事件类型-因此每个消费者还需要在可能不止一个发布者处订阅-Q2:这可能吗?我们已经了解到,您不能在多个位置订阅同一事件,请参阅:David Boike"一旦您在QueueName@WebServer1,您也将无法订阅来自的Message1QueueName@WebServer2."
其他悬而未决的问题:第三季度:如何检测消费者已永久关闭(如果它没有成功取消订阅总线)。->队列已满?!如何将其与仅失去网络连接一段时间的情况区分开来?
第4季度:如果订阅服务和EventStore之间的连接不可靠并失败,会发生什么?消费者在订阅服务上成功注册,但EventStore不知道新订阅,也不传递消息。。。
Q5:概述:NServiceBus如何处理队列?当消费者在很长一段时间内(例如几天)无法联系到时会发生什么?
Q1:这在某种程度上取决于您如何订阅消息。NServiceBus是在存在业务服务(有界上下文)的情况下构建的,这些业务服务不能共享数据。然而,在CQRS中,您有包含大量数据的胖事件,这些数据被发布,以便订阅者可以将信息存储在他们的读取模型中。例如,在用户界面中使用这种读取模型。通过普通UI或复合UI(从多个业务服务收集信息)。所以这取决于你在寻找什么。
Q2:可以订阅多个活动。但是,事件只有一个逻辑发布者。因此,事件"CustomerWasBilled"不能来自组件A和组件B。但是,您可以订阅许多不同的活动,当然每个发布者都可以有许多不同的订阅者。
[Udi]一个给定的发布服务器可以跨多个服务器进行扩展,NServiceBus将为您处理这一问题,而无需订阅每台机器。
Q3:我认为这是纯粹的行政管理。如果它应该保持在线并接收消息,那么队列就会被填满。如果它应该永久关闭/离线,并且消息没有得到处理,那么在组件关闭后,你会很快知道。但我强烈建议记录哪些订阅者和发布者相互连接,以及如果更改消息或组件会发生什么。
[Udi]如果是有序关闭,那么应该包括取消订阅。如果它是暂时的崩溃,那么您可以通过标准监控(WMI)来检测它。为了防止队列被填满,可以使用TimeToBeReceived属性定义何时丢弃消息。
Q4:这是在NServiceBus中处理的。它将订阅存储在数据存储中,数据存储可以是SQL Server、RavenDB&InMemory。但它也会将订阅保存在内存中,并定期检查是否添加了新的订阅。NServiceBus应该不是问题。
问题5:MSMQ本身就是可靠的。当然,如果你的整个服务器都崩溃了,所有的消息都在HD上炸了,那就是一个问题。如果组件在较长的天数内无法访问,则取决于SLA是否会发生这种情况。您可以监视传入队列或错误队列中的消息计数。也不要忘记DeadLetterQueue。但是NServiceBus还允许您监视处理消息所需的时间。
当一个组件在很长一段时间内(例如几天)无法访问时,业务部门应该决定该做什么。如果处理了重要的消息,则引入集群等。
希望这能帮助