RabbitMQ dead letter exchange never getting messages

前端 未结 7 939
陌清茗
陌清茗 2020-12-12 13:08

I\'m trying to setup my first RabbitMQ dead letter exchange, here are the steps I\'m using through the web admin interface:

  1. Create new DIRECT exchange with the
相关标签:
7条回答
  • 2020-12-12 13:31

    If you want all your queues to have same dead letter exchange it is easier to set a general policy:

    sudo rabbitmqctl -p /my/vhost/path set_policy DLX ".*" '{"dead-letter-exchange":"MyExchange.DEAD"}' --apply-to queues
    
    0 讨论(0)
  • 2020-12-12 13:33

    Create new DIRECT exchange with the name "dead.letter.test"

    Correct

    Create new queue "dead.letter.queue"

    Correct

    Bind "dead.letter.queue" to "dead.letter.test"

    Correct

    Create new queue "test1" with the dead letter exchange set to "dead.letter.test"

    I am assuming you are creating test1 queue and binding it to dead.letter.test exchange

    Send a message into "test1"

    If you want your message to be received by dead.letter.queue you will have to provide routing key while sending message and clients consuming dead.letter.queue should also use same routing key

    If you are publishing without routing key then only clients who are subscribed to test1 will receive the message.

    If you publish message to direct.letter.test exchange then all the queue will receive the message. It will work like a fanout exchange

    So, if you want dead.letter.queue to receive message you will have to publish message in that queue or you will have to use same routing key while publishing and subscribing and publish message to exchange

    0 讨论(0)
  • 2020-12-12 13:34

    Don't need to create FANOUT exchange if it is not compulsory.

    You can create DIRECT exchange using the same routing key which you have used already for other exchange. And also don't need to create a new queue for the new exchange. You can use existing queues with new exchange. You just need to bind that new exchange with the queue.

    Here is my receive.js file:

    var amqp = require("amqplib/callback_api");
    var crontab = require('node-crontab');
    
    amqp.connect("amqp://localhost", function (err, conn) {
    conn.createChannel(function (err, ch) {
        var ex = 'direct_logs';
        var ex2 = 'dead-letter-test';
        var severity = 'enterprise-1-key';
    
        //assert "direct" exchange
        ch.assertExchange(ex, 'direct', { durable: true });
        //assert "dead-letter-test" exchange
        ch.assertExchange(ex2, 'direct', { durable: true });
    
        //if acknowledgement is nack() then message will be stored in second exchange i.e. ex2="dead-letter-test"
        ch.assertQueue('enterprise-11', { exclusive: false, deadLetterExchange: ex2 }, function (err, q) {
            var n = 0;
            console.log(' [*] Waiting for logs. To exit press CTRL+C');
            console.log(q);
    
            //Binding queue with "direct_logs" exchange
            ch.bindQueue(q.queue, ex, severity);
            //Binding the same queue with "dead-letter-test"
            ch.bindQueue(q.queue, ex2, severity);
    
            ch.consume(q.queue, function (msg) {
                // consume messages via "dead-letter-exchange" exchange at every second.
                if (msg.fields.exchange === ex2) {
                    crontab.scheduleJob("* * * * * *", function () {
                        console.log("Received by latest exchange %s", msg.fields.routingKey, msg.content.toString());
                    });
                } else {
                    console.log("Received %s", msg.fields.routingKey, msg.content.toString());
                }
    
                if (n < 1) {
                    // this will executes first time only. Here I'm sending nack() so message will be stored in "deadLetterExchange"
                    ch.nack(msg, false, false);
                    n += 1;
                } else {
                    ch.ack(msg)
                    n = 0
                }
            }, { noAck: false });
        });
      });
    });
    
    0 讨论(0)
  • 2020-12-12 13:36

    If you want to use custom routing key on dead letter exchange you have to set x-dead-letter-routing-key when declaring working queue (in your case it is test1), otherwise default routing key will be used. In your case RabbitMQ broker detects cycling and simply drop rejected messages.

    What you need is to have x-dead-letter-exchange=dead.letter.test and x-dead-letter-routing-key=dead.letter.queue arguments set on test1 queue.

    0 讨论(0)
  • 2020-12-12 13:37

    In my case the problem was because the queue had

    ackMode="MANUAL"
    

    But I never set it (because a runtime exception), use Defaul ACK instead.

    0 讨论(0)
  • 2020-12-12 13:41

    Dead Letter Exchange without routing key and with direct exchange


    Follow the steps these will work for sure:-
    1. Create a new queue named 'dead_queue'.
    2. Create an exchange named 'dead_exchange' and type of exchange should be 'direct'.
    3. Bind 'dead_queue' and 'dead_exchange' without routing key.
    4. Create a new queue named 'test_queue' and set its 'x-dead-letter-exchange' name as 'dead_exchange'
    5. Create an exchange named 'test_exchange' and type of exchange should be 'direct'
    6. Bind 'test_exchange' and 'test_queue' without routing key.

    And at last we will check it. For this publish something on 'test_exchange' with argument 'expiration' set to 10000. After this when a message is publish on 'test_exchange' it will go to 'test_queue' and when a message is expired with in a queue it will look for DLX Parameter(Dead Letter Exchange name) there that message find the name 'dead_exchange' then that message will reach 'dead_exchange' deliver it to 'dead queue' .. If still you have any problem regarding this and if i miss understood your problem... write your problem i will surely look over it... Thanks..

    Note: Must publish the message on 'test_exchange' because that test_queue and test_exchange binding is without routing key and it will work fine but If you publish message on 'test_queue' default exchange and routing key will be used.Then after expiration of message queue tries to deliver that dead message to dead_exchange with some default routing key and message will not go to that queue.

    0 讨论(0)
提交回复
热议问题