本文介绍了多个消费者如何订阅同一个主题并在RabbitMQ中获得相同的消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我知道已经有类似问题的答案此处,但我仍然不确定这是因为 RabbitMQ 的不可能性还是因为我还没有进行足够的研究.

First of all, I know there is already an answer to a similar question here, but I am still not sure this is because of RabbitMQ's impossibility or because I haven't researched enough.

我来自 JS/Node 背景,事件发布/订阅模式的工作原理是这样的:当许多消费者使用发布/订阅模式订阅同一个主题时,每当某个生产者发布它时,所有消费者都应该收到相同的消息.

I come from JS/Node background where event pub/sub pattern works like this: when many consumers subscribe to the same topic with pub/sub pattern, all of them should get the same message whenever some producer publishes it.

我希望通过消息代理实现相同的模式.

I expect to implement the same pattern with a message broker.

例如:

消费者 1 监听 'request.user.#'

消费者 2 监听 'request.user.#'

消费者 3 监听 'request.#.#'

Producer 1 发布到主题 'request.user.add'

Producer 1 publishes to topic 'request.user.add'

Producer 2 发布到主题 'request.user.detail'

Producer 2 publishes to topic 'request.user.detail'

RabbitMQ 实际做了什么(根据这个 RabbitMQ 关于主题的例子)

Consumer 3 获得两条消息,而 Consumer 1Consumer 2 获得第一条消息,只有其中一个获得第二条消息留言.

Consumer 3 gets both messages, while either Consumer 1 or Consumer 2 gets the first message, and only either of them gets the second message.

我希望实现的内容

其中三个同时收到两条消息.

Three of them gets both messages.

您是否有任何想法通过消息代理(RabbitMQ 优先)来实现这一点?请指出我的问题中是否有遗漏或不清楚的地方.

Do you have any idea to implement this with a message broker (RabbitMQ in top priority)? Please point out if I miss something or am not clear somewhere in my question.

提前致谢.

使用解决方案进行

感谢@cantSleepNow,这里是Consumer 1Consumer 2 的代码(NodeJS),我在他的提示之后想出了:

Thanks to @cantSleepNow, here is the code (NodeJS) for Consumer 1 and Consumer 2 that I have come up with after his hint:

var amqp = require('amqplib/callback_api');

amqp.connect('amqp://localhost', (err, conn) => {
  conn.createChannel((err, ch) => {
    var ex = 'topic_exchange'; // Exchange name
    ch.assertExchange(ex, 'topic'); // Exchange with 'topic' type
    ch.assertQueue('', {exclusive: true}, (err, q) => {
      ch.bindQueue(q.queue, ex, 'request.user.#'); // Topic pattern
      ch.consume(q.queue, (msg) => {
        // Process message
      });
    });
  });
});

推荐答案

只需使用主题交换,让每个消费者使用适当的路由键声明自己的队列.

Well simply use the topic exchange and have each consumer declare it's own queue with appropriate routing key.

当你发布时,你发布到一个主题交换(我们称之为 E1)(例如)'request.user.add' 和所有绑定到 E1 的队列匹配路由键(因为我们在这里讨论的是主题)将收到消息.

When you're publishing, you are publishing to a topic exchange (let's call it E1) with (for example) 'request.user.add' and all the queues bound to E1 with the matching routing keys(since we are talking topics here) will get the message.

或者可以这样说:一条消息从一个队列中消费一次,从一个交换中消费的次数与绑定到它的队列一样多(使用适当的路由键).

Or maybe to put it like this: one message is consumed from one queue once, and from one exchange as many times as there are queues bound to it (with appropriate routing keys).

在@hirikarate 添加问题的解决方案后进行编辑

好吧,我不使用 javascript,但我会尽力提供帮助 :) 使用 exclusive 您是说只有一个消费者可以连接到队列,这是可以的.此外,如果您在每个消费者中创建一个具有唯一名称的队列,您将获得几乎相同的结果(显然区别在于允许其他消费者从中消费)同样,在 JS 中不知道,但应该有一个您使用给定名称创建队列的方式,或者让服务器将名称返回给您.否则看起来没问题,你只需要测试它.

Well, I don't use javascript, but I'll try to help :) With exclusive you're saying that only one consumer can connect to the queue, which is ok. Also if you create a queue with a unique name in each consumer you'd achieve almost the same (obviously the difference is that other consumers would be allowed to consume from it) Again, don't know in JS, but there should be a way that you create a queue with the given name, or have the server return the name to you. Other then that looks ok, you just need to test it.

这篇关于多个消费者如何订阅同一个主题并在RabbitMQ中获得相同的消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-06 04:21