【问题标题】:how to delete messages from a Queue in RabbitMQ immediately after they ve been sent如何在发送后立即从 RabbitMQ 中的队列中删除消息
【发布时间】:2019-04-23 12:18:14
【问题描述】:

所以我开始使用 RabbitMQ 并在网站 https://www.rabbitmq.com/tutorials/tutorial-one-javascript.html 上做教程,但我没有 100% 理解如何设置确认功能,以便队列在发送消息后立即删除消息,没关系消息是否会被消费。我正在尝试创建一个队列,该队列将在发送后立即删除所有消息

我尝试了教程中的示例,例如 hello world 示例显示 noAck 属性设置为 true ,这意味着我们没有确认消息,因此队列实际上应该在发送这些消息后删除这些消息,但这不是因为当我运行 send.js 3 次然后运行 ​​receive.js 时,我会收到 3 次 hello world 消息,这不是我想要的

 // this is send.js
   var amqp = require('amqplib/callback_api');

  amqp.connect('amqp://localhost', function(error0, connection) {
  if (error0) {
    throw error0;
  }
 connection.createChannel(function(error1, channel) {
    if (error1) {
        throw error1;
    }

    var queue = 'hello';
    var msg = 'Hello World!';

    channel.assertQueue(queue, {
        durable: false
    });
    channel.sendToQueue(queue, Buffer.from(msg));

    console.log(" [x] Sent %s", msg);
});
setTimeout(function() {
    connection.close();
    process.exit(0);
}, 500);
  });

   // this is receive .js
     var amqp = require('amqplib/callback_api');

 amqp.connect('amqp://localhost', function(error0, connection) {
if (error0) {
    throw error0;
}
connection.createChannel(function(error1, channel) {
    if (error1) {
        throw error1;
    }

    var queue = 'hello';

    channel.assertQueue(queue, {
        durable: false
    });

    console.log(" [*] Waiting for messages in %s. To exit press CTRL+C", 
   queue);

    channel.consume(queue, function(msg) {
        console.log(" [x] Received %s", msg.content.toString());
    }, {
        noAck: true
    });
});
});

例如,如果我运行 3 次 send.js,则可能会发生 2 种情况。情况 1 是消息将从接收方消费并完成。 case2 是它不会从接收器中消耗,在这种情况下,我希望将其删除,如果我在 send.js 一个月后运行 receive.js,我不希望消息被消耗,但我也希望我的队列耐用而不是排他性。 当我继续调用 send.js 并且消息将一直推送到该队列中时,这也是一个问题,然后如果我运行 receive.js,我将同时收到 1000 条消息,所以我的目标是避免这种情况。 感谢您的帮助

【问题讨论】:

  • 你描述的是消息队列的原理——生产者创建消息,然后所有的消息都被消费者按顺序消费。除了您不希望消息永远留在队列中之外,您没有提供任何特定要求。为此,您可以设置TTL
  • noAck:true 属性会将消息识别为已使用。它们是否真的被消耗并不重要,但让我感到困惑的是 noAck:True 在这里的用途是什么?似乎它什么也没做,因为如果消息是自动确认的,那么队列必须自动删除它们,但 Node js 中的 amqplib 不是这种情况
  • 恕我直言 noAck 表示无需手动确认,因此消息一旦被消费就会自动确认,无论它是否被处理。
  • 好的,但我的目标是不管它是否被消耗都会被删除。我不想运行 send.js 100 次,然后当我运行 receive.js 时,我会收到 100 次相同的消息,我该如何避免这种情况
  • 如果您不想使用它们,那么发送消息有什么意义呢?运行 receive.js 后你的预期行为是什么?

标签: javascript node.js rabbitmq amqp node-amqplib


【解决方案1】:

认为你想要的是,在再次阅读 cmets 和问题之后,你希望消息要么被传递给消费者,要么在目前无法传递的情况下被丢弃它进入队列。如果是这种情况,您可以在队列或单个消息上将 TTL 设置为 0。来自documentation的相关部分:

将 TTL 设置为 0 会导致消息在到达队列时过期,除非它们可以立即传递给消费者。

要设置队列的 TTL,在您的 JavaScript 客户端的情况下,您需要修改对 channel.assertQueue 的调用以包含 arguments 并将 x-message-ttl 设置为 0。以下是相关部分的示例:

var queue = 'hello';
channel.assertQueue(queue, {
    durable: false,
    arguments: {
        "x-message-ttl": 0
    }
});

更多详细信息,请咨询amqp.node documentation

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-20
    • 1970-01-01
    • 2015-11-05
    • 1970-01-01
    • 2020-10-24
    • 2011-03-26
    • 1970-01-01
    相关资源
    最近更新 更多