如何使用交换重用RabbitMQ队列?

时间:2017-01-19 15:39:34

标签: node.js rabbitmq rabbitmq-exchange

我将解释我想要实现的目标,然后解释我所做的事情(没有结果)

我有两个节点服务连接它们与RabbitMQ ussing交换(主题):

enter image description here

我想要的是关闭C1,同时仍向something.orange.something发送消息。然后我想再次重新启动C1并收到我丢失的所有消息。

现在发生的事情是每次重新启动我的消费者时都会创建一个新队列,并在我的交换中使用相同的路由键创建一个新绑定。所以我现在有两个队列接收相同的信息。

如果我使用param {exclusive: true}配置我的队列,我解决了部分问题,我不再有没有接收器的队列,但仍然遇到同样的问题...没有活动接收器发送的所有消息都将丢失

有可能吗?

这是我的代码:

发件人

'use strict';

const amqp = require('amqplib/callback_api');
const logatim = require('logatim');
logatim.setLevel('info')

amqp.connect('amqp://localhost', (err, conn) => {
  conn.createChannel((err, ch) => {
    let ex = 'direct_colors';
    let args = process.argv.slice(2);
    let colors = ['colors.en.green', 'colors.en.yellow', 'colors.es.red']

    ch.assertExchange(ex, 'topic', {durable: true});

    setInterval(() => {
      let color = colors[Math.floor(Math.random() * 3)];
      let msg = `This is a ${color} message`;
      ch.publish(ex, color, new Buffer(msg));

      logatim[color.split('.').pop()].info(msg);
    }, 1000);
  });
});

敬意

'use strict';

const amqp = require('amqplib/callback_api');
const logatim = require('logatim');
logatim.setLevel('info');
const args = process.argv.slice(2);

amqp.connect('amqp://localhost', (err, conn) => {
  conn.createChannel((err, ch) => {
    var ex = 'direct_colors';

    ch.assertExchange(ex, 'topic', {durable: true});

    ch.assertQueue('', {exclusive: true, durable: true}, (err, q) => {
      logatim.green.info(' [*] Waiting for logs. To exit press CTRL+C');

      args.forEach((arg) => {
        ch.bindQueue(q.queue, ex, arg);
      });

      ch.consume(q.queue, (msg) => {
        logatim[msg.fields.routingKey.split('.').pop()].info(` [x] ${msg.content.toString()}`);
      });
    });
  });
});

1 个答案:

答案 0 :(得分:2)

您需要命名队列。在接收器类中声明队列时,请给它一个众所周知的名称(常量),如

ch.assertQueue('my_service_1_queue', {durable: true}, ...

它们的基本示例在RabbitMQ Tutorial

当您的消费者关闭并重新启动时,它将从同一个命名队列消耗。 注意:您不需要那里的独占队列,因为当您的消费者关闭时它将被删除。