RabbitMQ连续有一个专用的消费者消费消息

时间:2018-12-04 16:29:53

标签: node.js rabbitmq amqp

我有一个场景,在给定的主题上,我需要一个一个地使用每条消息,执行一些异步任务,然后再使用下一条。我正在使用rabbitmqamqp.node

我能够以prefetch为1来实现。当然这不是实际的解决方案,因为这会锁定整个频道,并且该频道有多个主题。

到目前为止,这是我的制作人:

const getChannel = require("./getChannel");
async function run() {
    const exchangeName = "taskPOC";
    const url = "amqp://queue";
    const channel = await getChannel({ url, exchangeName });
    const topic = "task.init";
    let { queue } = await channel.assertQueue(topic, {
        durable: true
    });
    const max = 10;
    let current = 0;
    const intervalId = setInterval(() => {
        current++;
        if (current === max) {
        clearInterval(intervalId);
        return;
        }
        const payload = JSON.stringify({
        foo: "bar",
        current
        });

        channel.sendToQueue(queue, Buffer.from(payload), { persistent: true });
    }, 3000);

}
run()
.then(() => {
    console.log("Running");
})
.catch(err => {
    console.log("error ", err);
});

这是我的消费者

const getChannel = require("./getChannel");
async function run() {
    const exchangeName = "taskPOC";
    const url = "amqp://queue";
    const channel = await getChannel({ url, exchangeName });
    channel.prefetch(1);
    const topic = "task.init";
    const { queue } = await channel.assertQueue(topic, {
        durable: true
    });
    channel.bindQueue(queue, exchangeName, topic);
    let last = new Date().getTime();
    channel.consume(
        queue,
        msg => {
        const now = new Date().getTime();
        console.log(
            " [x] %s %s:'%s' ",
            msg.fields.routingKey,
            Math.floor((now - last) / 1000),
            msg.content.toString()
        );
        last = now;
        setTimeout(function() {
            channel.ack(msg);
        }, 10000);
        },
        { exclusive: true, noAck: false }
    );
}
run()
.then(() => {
    console.log("Running");
})
.catch(err => {
    console.log("error ", err);
});

RabbitMQ上有什么方法可以做到这一点,还是需要在我的应用程序上进行处理?

谢谢。

1 个答案:

答案 0 :(得分:0)

您可以使用使用者预取设置(请参见https://www.rabbitmq.com/consumer-prefetch.html)。对于amqp节点,您可以使用预取功能设置此选项:

channel.prefetch(1, false); // global=false

在这种情况下,通道上的每个使用者均将预取1。如果您希望为每个使用者具有不同的配置,则应创建更多通道。

希望这会有所帮助。