技术堆栈:
- .Net 4.6.1
- 二郎18.3
- 语言:C#
- NServiceBus 6
- RabbitMQ 3.6.3
- Windows 7
上下文:我们正试图在RabbitMQ传输上的NServiceBus中实现一个具有智能订阅的哑事件发布器。
- 所有感兴趣的接收者都订阅了一个事件
- 发布服务器将事件发布到事件通道
- 所有订阅者都会收到事件的副本
- 注意,我并没有说每种类型的订阅者都会收到一份消息。如果有多个服务实例在运行,并且它们都对某个事件有活动订阅,则订阅服务的每个实例都应该获得消息的副本
然而,NServiceBus的发布-订阅概念将发布的事件传递给给定通道上的一个且仅一个接收器。在我们的案例中,是给定订阅服务的一个实例。
我不太愿意列出消息传递的"模式",因为它们的命名或描述似乎并不一致。然而,我相信我们确实在尝试实现企业集成模式(Hohpe和Woolf)书中发布-订阅通道消息传递模式的"多播"版本。
问题陈述:我们的商业案例是:
- 我们有一个配置服务,它为我们更广泛的应用程序中的所有其他服务提供应用程序配置
- 每个服务在启动时通过发送ConfigurationRequest消息从配置服务请求其配置
- 配置服务通过ConfigurationResponse来回复发出ConfigurationRequest的特定实例。这是使用NServiceBus的全双工(通常称为请求-响应)功能完成的
- 有一个网站可以全局修改配置。当它这样做时,它会用UpdateConfiguration命令通知配置服务
- 配置服务发布所有其他服务都订阅的ConfigurationUpdated事件
- 每个服务可以有多个实例在多个服务器上运行。服务的所有实例都需要更新其配置,而不仅仅是一个实例
- 每个服务实例都使用不同的鉴别器调用NServiceBus的EndpointConfiguration.MakeInstanceUniquelyIdentifiable
- 目前,当我们发布ConfigurationUpdated事件时,每种服务类型只有一个实例会收到消息。事件是分布式循环的,而不是每个实例都获得消息的副本
我们已经解决了这个问题,我们记录了运行服务实例,并将ConfigurationUpdated事件(作为NServiceBus中的命令)分别发送给它们中的每一个,但Pub-Sub暗示我们应该有愚蠢的发布者和智能订阅者,而我们的解决方法恰恰相反。。。我们的发布者查找每个订阅者的列表,并隐式地发送给它。订户端是否缺少一些配置,允许每个服务的每个实例获得已发布的ConfigurationUpdated事件的副本?如果没有,我应该在NServiceBus中从哪里开始实现这样的功能?也许是路由拓扑?
我对nserviebus不够熟悉,不知道如何使用该工具集,但RabbitMQ实现将是一个"扇出"交换,每个使用者有一个队列。
绑定到扇出交换机的每个队列都将获得消息的副本。如果每个队列都有一个使用者,那么您将向每个使用者发送一份消息副本。
听起来好像有多个消费者连接到同一个队列。也许有一种方法可以告诉nserviebus为每个使用者实例创建一个队列?
p.s.您对pub-sub模式是多播的看法是正确的。我在我的RMQ模式电子书中谈到了这一点(https://leanpub.com/rmq-patterns)这也是EIP书中所说的。