RabbitMq dead letter queue

Keywords: RabbitMQ

When the messages in the queue expire, or reach the maximum length and are deleted, or reach the maximum space and are deleted, the deleted information can be pushed to other switches, and other consumers can subscribe to the deleted messages and process them.

Preparation elements: a producer, a normal consumer (with a normal switch, a routing key, a normal queue) and a consumer (with a death switch, a death routing key, a death queue) who processes expired messages

Producer:

@Component
public class MsgProducer {
    //Switch name
    private static final String EXCHANGE_NAME = "amqp-hello";
    private static final String EXCHANGE_NAME2 = "amqp-hello2";
    //Key "mqkey" bound between switch and switch
    private static final String ExCHANEROUTING_KEY = "mqkey";
    //Column names
    private static final String QUEUE_NAME = "Hello-Queue1";
    //routingkey name
    private static final String ROUTING_KEY = "key-Queue";
    //Dead routing key
    private static final String DEADROUTING_KEY = "deadkey-Queue";
    //Death switch
    private static final String DEADEXCHANGE_NAME = "deadamqp-hello";
    //The name of the opposite column to process the death message
    private static final String DEADQUEUE_NAME = "deadHello-Queue1";

     public static void main(String[] args) throws Exception{
        String message;
        //1. Get connection
        Connection connection = RabbitConnectionUtil.getConnection("localhost", 5672, "/", "guest", "guest");
        //2. Declaration channel
        Channel channel = connection.createChannel();
        //Switch
        channel.exchangeDeclare(EXCHANGE_NAME, "direct", false, false, null);
        Map<String, Object> arguments = new HashMap<String, Object>();
        arguments.put("x-message-ttl", 15000);
        //Connect the two switches together through these two parameters!!
        arguments.put("x-dead-letter-exchange", DEADEXCHANGE_NAME);
        arguments.put("x-dead-letter-routing-key", DEADROUTING_KEY);
        //3. Declare (create) queue B: whether the durable is persistent or not. The declaration of queue is stored in memory by default. If true: rabbitmq restarts the queue, it will not be lost, but the message is missing. false: the queue and the message are all gone
        //b1:exclusive: exclusive or not. It has two functions. One is whether the queue will be deleted automatically when the connection is closed
        //b2:autoDelete: delete automatically. When the last consumer disconnects, the messages in the queue will be deleted automatically. When consumers = 0, the messages in the queue will be deleted automatically
        channel.queueDeclare(QUEUE_NAME,true,false,false,arguments);
        //Bind the switch and queue to the switch connected to the queue with exchange [name] through the routing key
        channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,ROUTING_KEY);
        //Death switch
        channel.exchangeDeclare(DEADEXCHANGE_NAME, "direct", false, false, null);
        //Queue of death information
        channel.queueDeclare(DEADQUEUE_NAME,true,false,false,null);
        //Bind the dead switch and the dead letter queue with the dead route key. Deadexchange [name] is the dead switch connected to the dead letter queue
        channel.queueBind(DEADQUEUE_NAME,DEADEXCHANGE_NAME,DEADROUTING_KEY);
        for (int i=0;i<20;i++){
            //4. Define message content
            message = "hello rabbitmq-";
            //5. When publishing messages, routingkey is used to specify how to assign information to multiple consumers
            //Basic properties props -- the basic properties of a message, such as routing headers. byte[] body -- message body
            //void basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body) throws IOException;
            //Note that exchange [name] here is the switch connected to the producer!! Messageproperties.persistent'text'plan represents message persistence (there are other ways to set persistence for several messages separately)
            channel.basicPublish(EXCHANGE_NAME, ROUTING_KEY,null,(message+i).getBytes());
            System.out.println("[x] send'" + (message+i).toString() + "'");
        };
        //6. Close channels and connections
        channel.close();
        connection.close();
      }
   }
 }

The key codes are as follows:

Deadexhange? Name
Routing key: routing key

 Map<String, Object> arguments = new HashMap<String, Object>();
 arguments.put("x-message-ttl", 15000);
 //Connect the two switches together through these two parameters!!
 arguments.put("x-dead-letter-exchange", DEADEXCHANGE_NAME);
 arguments.put("x-dead-letter-routing-key", DEADROUTING_KEY);
 //Death switch, put the death route key into the normal queueDeclare
 channel.queueDeclare(QUEUE_NAME,true,false,false,arguments);

Consumer MsgReceiver1 processing normal messages:

@Component
public class MsgReceiver1 {
 //Switch name
    private static final String EXCHANGE_NAME = "amqp-hello";
    private static final String EXCHANGE_NAME2 = "amqp-hello2";
    //Key "mqkey" bound between switch and switch
    private static final String ExCHANEROUTING_KEY = "mqkey";
    //Column names
    private static final String QUEUE_NAME = "Hello-Queue1";
    //routingkey name
    private static final String ROUTING_KEY = "key-Queue";
    //Dead routing key
    private static final String DEADROUTING_KEY = "deadkey-Queue";
    //Death switch
    private static final String DEADEXCHANGE_NAME = "deadamqp-hello";
    //The name of the opposite column to process the death message
    private static final String DEADQUEUE_NAME = "deadHello-Queue1";
   
     public static void main(String[] args)  throws Exception {
        Connection connection = RabbitConnectionUtil.getConnection("127.0.0.1", 5672, "/", "guest", "guest");
        Channel channel = connection.createChannel();
        Map<String, Object> arguments = new HashMap<String, Object>();
        arguments.put("x-message-ttl", 15000);
        //Connect the two switches together through these two parameters!!
        arguments.put("x-dead-letter-exchange", DEADEXCHANGE_NAME);
        arguments.put("x-dead-letter-routing-key", DEADROUTING_KEY);
        //3. Declaration queue
        channel.queueDeclare(QUEUE_NAME, true, false, false, arguments);
        //You need to set the principle that every time you get the number of messages from the queue, you can have more than one job. You can't stop when you're done quickly!
        channel.basicQos(1);
        // channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,ROUTING_KEY1);
        // channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,ROUTING_KEY2);
        //4. Define the consumers of the queue
        QueueingConsumer queueingConsumer1 = new QueueingConsumer(channel);
        /*
        true:Indicates automatic confirmation. As long as the message is obtained from the queue, whether or not the consumer successfully consumes the message after obtaining it, the message will be considered as successfully consumed
        false:Indicates manual confirmation. After the consumer obtains the message, the server will mark the message as unavailable and wait for the consumer's feedback,
                If the consumer has not responded, the message will remain unavailable, and the server will think that the consumer has hung up and will not send a message to him,
                Until the consumer feedback. For example: channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
     */
        //b:ack
        channel.basicConsume(QUEUE_NAME, false,queueingConsumer1);
        // channel.basicConsume(QUEUE_NAME,true,queueingConsumer2);
        //6. Get message
        while (true) {
            anInt += 1;
            QueueingConsumer.Delivery delivery1 = queueingConsumer1.nextDelivery();
            // QueueingConsumer.Delivery delivery2 = queueingConsumer2.nextDelivery();
            String message1 = new String(delivery1.getBody());
            // String message2 = String.valueOf(delivery2.getBody());
            System.out.println("[" + String.valueOf(anInt) + "]:receve msg:" + message1);
            //Manually confirm whether the ACK is processed in batch. true: all messages smaller than deliveryTag will be ack once
            channel.basicAck(delivery1.getEnvelope().getDeliveryTag(), false);
            // System.out.println("[x] Received '" + message2 + "'");
            Thread.sleep(500);
        }
    }
}

Consumer handling expired messages MsgReceiver2

@Component
public class MsgReceiver2 {
    private static int  anInt = 0;
    //Switch name
    private static final String EXCHANGE_NAME = "amqp-hello";
    private static final String EXCHANGE_NAME2 = "amqp-hello2";
    //Key "mqkey" bound between switch and switch
    private static final String ExCHANEROUTING_KEY = "mqkey";
    //Column names
    private static final String QUEUE_NAME = "Hello-Queue1";
    //routingkey name
    private static final String ROUTING_KEY = "key-Queue";
    //Dead routing key
    private static final String DEADROUTING_KEY = "deadkey-Queue";
    //Death switch
    private static final String DEADEXCHANGE_NAME = "deadamqp-hello";
    //The name of the opposite column to process the death message
    private static final String DEADQUEUE_NAME = "deadHello-Queue1";
    //routingkey name
   // private static final String ROUTING_KEY1 = "key1-Queue";
    private static final String ROUTING_KEY2 = "key2-Queue";
    public static void main(String[] args)  throws Exception {
        Connection connection = RabbitConnectionUtil.getConnection("127.0.0.1", 5672, "/", "guest", "guest");
        Channel channel = connection.createChannel();
        //3. Declaration queue
        channel.queueDeclare(DEADQUEUE_NAME, true, false, false, null);
        //When polling, you need to set the principle that every time you get the number of messages from the queue, you can have more than one job. You can't stop when you're done quickly! Poll required
        //This doesn't work
        channel.basicQos(1);
        // channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,ROUTING_KEY1);
        // channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,ROUTING_KEY2);
        //4. Define the consumers of the queue
        QueueingConsumer queueingConsumer1 = new QueueingConsumer(channel);
        /*
    true:Indicates automatic confirmation. As long as the message is obtained from the queue, whether or not the consumer successfully consumes the message after obtaining it, the message will be considered as successfully consumed
    false:Indicates manual confirmation. After the consumer obtains the message, the server will mark the message as unavailable and wait for the consumer's feedback,
    If the consumer has not responded, the message will remain unavailable, and the server will think that the consumer has hung up and will not send a message to him,
    Until the consumer feedback. For example: channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
     */
        //b:ack
        channel.basicConsume(DEADQUEUE_NAME, false, queueingConsumer1);
        // channel.basicConsume(QUEUE_NAME,true,queueingConsumer2);
        //6. Get message
        while (true) {
            anInt += 1;
            QueueingConsumer.Delivery delivery1 = queueingConsumer1.nextDelivery();
            // QueueingConsumer.Delivery delivery2 = queueingConsumer2.nextDelivery();
            String message1 = new String(delivery1.getBody());
            // String message2 = String.valueOf(delivery2.getBody());
            System.out.println("[" + String.valueOf(anInt) + "]:receve msg:" + message1);
            //Manually confirm whether the ACK is processed in batch. true: all messages smaller than deliveryTag will be ack once
            channel.basicAck(delivery1.getEnvelope().getDeliveryTag(), false);
            // System.out.println("[x] Received '" + message2 + "'");
            Thread.sleep(500);
        }
    }

Start with multiple consumers and start with producers. Finally, after running the producer, it is found that MsgReceiver2 is waiting. When MsgReceiver1 consumes the normal message, the expired message MsgReceiver2 will start to consume

Operation result:

50 producers

[x] send'hello rabbitmq-0'
[x] send'hello rabbitmq-1'
[x] send'hello rabbitmq-2'
[x] send'hello rabbitmq-3'
[x] send'hello rabbitmq-4'
[x] send'hello rabbitmq-5'
[x] send'hello rabbitmq-6'
[x] send'hello rabbitmq-7'
[x] send'hello rabbitmq-8'
[x] send'hello rabbitmq-9'
[x] send'hello rabbitmq-10'
[x] send'hello rabbitmq-11'
[x] send'hello rabbitmq-12'
[x] send'hello rabbitmq-13'
[x] send'hello rabbitmq-14'
[x] send'hello rabbitmq-15'
[x] send'hello rabbitmq-16'
[x] send'hello rabbitmq-17'
[x] send'hello rabbitmq-18'
[x] send'hello rabbitmq-19'
[x] send'hello rabbitmq-20'
[x] send'hello rabbitmq-21'
[x] send'hello rabbitmq-22'
[x] send'hello rabbitmq-23'
[x] send'hello rabbitmq-24'
[x] send'hello rabbitmq-25'
[x] send'hello rabbitmq-26'
[x] send'hello rabbitmq-27'
[x] send'hello rabbitmq-28'
[x] send'hello rabbitmq-29'
[x] send'hello rabbitmq-30'
[x] send'hello rabbitmq-31'
[x] send'hello rabbitmq-32'
[x] send'hello rabbitmq-33'
[x] send'hello rabbitmq-34'
[x] send'hello rabbitmq-35'
[x] send'hello rabbitmq-36'
[x] send'hello rabbitmq-37'
[x] send'hello rabbitmq-38'
[x] send'hello rabbitmq-39'
[x] send'hello rabbitmq-40'
[x] send'hello rabbitmq-41'
[x] send'hello rabbitmq-42'
[x] send'hello rabbitmq-43'
[x] send'hello rabbitmq-44'
[x] send'hello rabbitmq-45'
[x] send'hello rabbitmq-46'
[x] send'hello rabbitmq-47'
[x] send'hello rabbitmq-48'
[x] send'hello rabbitmq-49'

MsgReceiver1 normally processes 31

[1]:receve msg:hello rabbitmq-0
[2]:receve msg:hello rabbitmq-1
[3]:receve msg:hello rabbitmq-2
[4]:receve msg:hello rabbitmq-3
[5]:receve msg:hello rabbitmq-4
[6]:receve msg:hello rabbitmq-5
[7]:receve msg:hello rabbitmq-6
[8]:receve msg:hello rabbitmq-7
[9]:receve msg:hello rabbitmq-8
[10]:receve msg:hello rabbitmq-9
[11]:receve msg:hello rabbitmq-10
[12]:receve msg:hello rabbitmq-11
[13]:receve msg:hello rabbitmq-12
[14]:receve msg:hello rabbitmq-13
[15]:receve msg:hello rabbitmq-14
[16]:receve msg:hello rabbitmq-15
[17]:receve msg:hello rabbitmq-16
[18]:receve msg:hello rabbitmq-17
[19]:receve msg:hello rabbitmq-18
[20]:receve msg:hello rabbitmq-19
[21]:receve msg:hello rabbitmq-20
[22]:receve msg:hello rabbitmq-21
[23]:receve msg:hello rabbitmq-22
[24]:receve msg:hello rabbitmq-23
[25]:receve msg:hello rabbitmq-24
[26]:receve msg:hello rabbitmq-25
[27]:receve msg:hello rabbitmq-26
[28]:receve msg:hello rabbitmq-27
[29]:receve msg:hello rabbitmq-28
[30]:receve msg:hello rabbitmq-29
[31]:receve msg:hello rabbitmq-30

MsgReceiver2 processes 19 expired messages

[1]:receve msg:hello rabbitmq-31
[2]:receve msg:hello rabbitmq-32
[3]:receve msg:hello rabbitmq-33
[4]:receve msg:hello rabbitmq-34
[5]:receve msg:hello rabbitmq-35
[6]:receve msg:hello rabbitmq-36
[7]:receve msg:hello rabbitmq-37
[8]:receve msg:hello rabbitmq-38
[9]:receve msg:hello rabbitmq-39
[10]:receve msg:hello rabbitmq-40
[11]:receve msg:hello rabbitmq-41
[12]:receve msg:hello rabbitmq-42
[13]:receve msg:hello rabbitmq-43
[14]:receve msg:hello rabbitmq-44
[15]:receve msg:hello rabbitmq-45
[16]:receve msg:hello rabbitmq-46
[17]:receve msg:hello rabbitmq-47
[18]:receve msg:hello rabbitmq-48
[19]:receve msg:hello rabbitmq-49
171 original articles published, 10 praised, 10000 visitors+
Private letter follow

Posted by dirkers on Thu, 13 Feb 2020 06:31:25 -0800