我安装了一个nodeJS服务器使用的rabbitMQ。我使用rabbit.js库与rabbit进行交互,到目前为止我对它很满意。
在fanout模式下,同一队列上有多个订阅者,每个节点既是订阅者,也是发布者这对我来说很好,工作得很好,因为有很多情况下,我想通知所有的服务器关于一些更新发生在这些节点之一(这也是一个出版商…)
我偶然发现了一种情况,我需要向队列上的所有侦听器发送消息,除了发送消息的侦听器(它也是同一队列上的侦听器)。
我事先不知道谁在监听(可能有一个,也可能有数百万个),所以我不能通过一些白名单路由规则将它路由到某些特定的节点。它必须是某种排除通配符路由规则(某种黑名单)。例如,将此消息发送给所有侦听的不符合我自己唯一id的人…
可以用rabbit.js完成吗?它甚至可以在rabbitmq中以某种方式完成吗?
我不太了解兔子…所以对我温柔点吧:)
顺便说一句,如果你知道如何使用rabbit.js,那就更好了…
编辑::
根据德里克·贝利的要求这是我需要这个的原因
我有一个系统,其中有许多负载均衡的nodeJS服务器作为web服务运行。它们彼此之间完全透明。它们都不知道还有哪些节点存在。我希望保持这种方式,因为这种分离使我更容易通过添加和删除其他"并行"节点来更好地扩展。
每个节点都有自己的内存本地缓存服务。我偶然发现了一种情况,在这种情况下,单个节点更新了一些实体。现在我需要使这个节点能够通知所有其他并行节点(可能在缓存中有相同的实体)使其无效。
的问题是,发送消息的节点(更新节点)也将接收消息,因为他也是一个侦听器。所以我想让他把自己排除在那个特定信息的接收者名单之外……因此需要一些路由黑名单。(他知道他自己,所以我可以让他去每个人,除了他自己的身份…但他甚至不知道另一端是否有人在听……所以它绝对不能是白名单)
希望现在我的需求更明确了。
我已经想到了一个解决我的问题的方法,但它需要我这边的额外开发,我想通过使用兔子当前的能力来避免它(如果可能的话)我可以给消息的内容添加一个唯一的ID。然后发送节点可以识别该消息来自他,并忽略该消息。但正如您显然可以理解的那样,这可能会变得棘手,因为我需要考虑额外的陷阱和其他可能失败的边缘情况…
如果有人能告诉我如何使用一些兔子现有的配置,我会很高兴听到如何:)
不知道为什么我回答这个问题(因为我是第一个问它的人)我认为我的解决方案会帮助别人。
无论如何,我从来没有真正在整个amqp体系结构中找到一个解决方案。所以我发明了我自己的解决方案:)我所做的是在每个节点上创建一个内部服务,将这种"业余无线电风格"的消息发送给除了他自己以外所有关心收听的人。
此服务在传递给rabbitMQ之前为在此交换上发送的每个消息添加唯一的哈希值。并将散列保存在本地集合中。
在此交换中接收消息的每个节点,首先测试他是否是发送该消息的节点(通过验证消息哈希是否在他的"已发送消息"队列中可用)。
如果他在集合中检测到该消息,则本地服务忽略该消息如果他没有检测到它,他不会忽略该消息并将其传递给应该处理它的代码段
有一条无用的消息被发送在此队列上发送的每条消息都有一些代码开销
但最重要的是,它像一个魅力
希望能帮到别人
我真的相信这种只有发送方没有接收到消息的"业余无线电风格"交换可能是有用的
有人认为我应该联系设计amqp架构的人,让他们添加它吗?:)
这应该是可能的…但这可能有点棘手,或者需要一个不同于你目前所做的设置。
有一点需要考虑:使用fanout交换意味着所有被绑定的队列都将接收到消息。如果需要阻止某些队列获取消息,那么fanout可能是个坏主意。
不过,这很大程度上取决于要发送的消息。如果有特定类型的消息需要以不同的方式处理,那么您可能只需要为该类型的消息使用不同的交换/队列绑定。
关于黑名单…我不知道这是否可能。主题交换允许路由关键组件的白名单。
例如, foo.*.bar
的绑定将允许任何以"foo."开头、中间有任何单词、以"。bar"结尾的路由键。
据我所知,没有办法将路由关键段列入黑名单。
似乎您最好的选择是重新考虑如何配置您的系统。
如果你张贴一个你需要做什么的例子可能会有所帮助…你在处理什么类型的消息,为什么你有这么多的消费者,包括生产者消费相同的消息。,
注。我使用了rabbit.js一段时间,发现我不喜欢它的局限性。我切换到wascally
库,并在其上为节点构建自己的rabbus
库。你可以去看看……它们更加灵活,rabbus提供了许多开箱即用的相同模式。