rabbitmq simple introduction

Posted by monkeynote on Sun, 13 Feb 2022 15:40:08 +0100

1, rabbitMq concept

rabbitMq is a message oriented middleware that receives and uses messages for third parties. Just like express delivery, merchants are producers, express stations are MQ, and users are consumers.

2, Why rabbitMq

  1. decoupling
    For example, system A of the company needs to push data to other different systems. In this way, the coupling between subsystems becomes higher. System A needs to consider A series of messy factors, such as whether other systems hang up and need to push, wait and wait again. At this time, if rabbitMq is used, system A only needs to consider pushing the data to rabbitMq. If other systems need to consume, they can go to system A to obtain it by themselves, which can effectively decouple system A from other systems.
  2. Peak clipping
    For example, the company's business has a peak period. For example, the amount of data written in the morning is w/s, while the bearing capacity of the database is only k/s, the system may crash and get stuck. However, if the message is written to rabbitmq, rabbitmq controls the message reading speed to be less than the system capacity, so that it will not hang up even in peak periods.
  3. asynchronous
    For example, system A has requirements. If A certain piece of data is accepted, it needs to be written to system A and other systems, and the time is cumulative. However, if the data is sent to other rabbitmq and written by each system, the writing time will be greatly reduced.

3, Disadvantages of using rabbitMq

  1. System availability
    The addition of rabbitmq leads to the increase of system components and the difficulty of deployment and operation and maintenance. And if rabbitmq hangs up, it will also affect the use of the system.
    2. Data consistency
    Because rabbitmq is added, the number of issues to be considered will also increase. For example, the message is lost, the message is consumed repeatedly, whether the message is successfully sent but successfully consumed by the consumer, and so on

4, Selection of MQ

nameadvantageshortcomingApplicable scenario
activeMQThe throughput of a single machine is 10000, the timeliness is ms, the availability is high, and the probability of data loss is low.The official community is now for ActiveMQ 5 The version maintenance of X is less and less, and high-throughput scenarios are less used.With the emergence of other MQS, the usage of ActiveMQ in the early stage gradually decreases, and it has not been verified by the large-scale throughput scenario, and the community is not very active, so it is not recommended.
KafkaSingle machine throughput is one million level, timeliness is ms level, availability is very high, and message reliability can be configured with 0 loss. And it is distributed. One data has multiple copies, and a few machines will not lose data when they go down.When a single machine has more than 64 queues / partitions, the CPU will be significantly higher. The more queues, the higher the response time of sending messages. Consumption failed. Retry is not supported.It is mainly used for log collection and transmission, which is generally used by large companies
RocketMQThe single machine has a throughput of 100000 levels, high availability, supports distributed, message reliability can achieve 0 loss, good scalability, and supports the accumulation of one billion levels of messages.Not many clients are supported. At present, only java and c + + are supported.It is mainly used in the financial field and is widely used by Alibaba in order, transaction, reset, message push and other scenarios.
RabbitMQWritten in erlang language, it has good performance, 10000 class single machine throughput and timeliness μ s-level, high availability, basically no loss of message reliability, and supports a large number of other languages, with high community activity and high update frequency.The commercial version needs to be charged, and the learning cost is high.Convenient interface management and complete functions. If the amount of data is small, it can be recommended for small and medium-sized companies.

5, Installing rabbitmq

ps: because the required packages are downloaded slowly, they can be downloaded directly from here (those with better network can be ignored): https://download.csdn.net/download/weixin_40496191/80386784

  1. Because rabbitmq requires erlang support, you need to determine the corresponding relationship between erlang and rabbitmq before downloading the package: https://www.rabbitmq.com/which-erlang.html
  2. Install ErLang
    1) Download: wget https://github.com/rabbitmq/erlang-rpm/releases/tag/v21.3.1/erlang-21.3.1-1.el7.x86_64.rpm
    2) Installation: RPM -ivh erlang-21.3.1-1 el7. x86_ 64.rpm
    ps1: if the installation is wrong: rabbitmq-server-3.8.8-1 el7. noarch. rpm: not an rpm package (or no manifest). This is because github network access is slow and may not be fully downloaded. Therefore, if wget has a problem, you can choose to log in to the website directly, download the package, and then transfer it to linux!
    ps2: the downloaded version el7 is based on linux and can be viewed through uname -a:
  3. Installing RabbitMQ
    1) Download dependency: yum install -y socat
    2) Download package: wget https://github.com/rabbitmq/rabbitmq-server/releases/tag/v3.8.8/rabbitmq-server-3.8.8-1.el7.noarch.rpm
    3) Installation: RPM - IVH rabbitmq-server-3.8.8-1 el7. noarch. rpm
    ps: if the installation reports an error and the download is incomplete, the solution is as follows!
  4. Start RabbitMQ: systemctl start RabbitMQ server
  5. Set RabbitMQ startup self startup: systemctl enable RabbitMQ server
    ps1: related commands - close RabbitMQ: rabbitmqctl stop
    ps2: related commands - restart RabbitMQ: systemctl restart RabbitMQ server
    ps3: related commands - plug-in list: rabbitmq plugins list
    ps4: related command - start plug-in: rabbitmq plugins enable XXX (XXX is the plug-in name)
    ps5: related commands - Disable plug-ins: rabbitmq plugins disable XXX
  6. Check the status after startup: rabbitmqctl status, systemctl status rabbitmq server
  7. Create a new user
    1) New user: rabbitmqctl add_user admin admin
    2) Grant administrator permission: rabbitmqctl set_user_tags admin administrator
    3) Set the virtual machine permissions that admin can use: rabbitmqctl add_vhost admin–>rabbitmqctl set_ permissions -p admin admin ".*" ".*" ".*"
  8. Viewing user: rabbitmqctl list_users
  9. Restart RabbitMQ: systemctl restart RabbitMQ server
  10. View page: http://192.168.248.10:15672

    Enter the account password: admin/admin

    Entering this interface indicates that the installation is successful (because some code operations have been done here, the interface is not original, and the newly installed one is somewhat different from mine)

6, RabbitMQ working principle diagram

  1. producer is the system that sends messages.
  2. connection: the TCP channel that connects to the RabbitMQ server
  3. exchange and queue: messages are sent to the switch first, and then forwarded to the queue by the switch according to the rules. A switch can correspond to multiple queues. If the switch is not specified when working, the default switch will be used.
  4. consumer: the system that consumes the queued messages last.

7, Code implementation - simple work

Workflow

Since our subsequent tests will connect to the rabbitmq server, a public connection class is created here.

  1. Create public connection class
package com.rabbitmqUtils;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @author Naive heat
 * Create channel
 * @create 2022-02-08 16:26
 * @desc
 **/
public class RabbitmqUtils {
    //Queue name
    public static final String RABBITMQ_QUEUE = "RABBITMQ_QUEUE";
    //Switch name
    public static final String RABBITMQ_EXCHANGE = "RABBITMQ_EXCHANGE";

    public static Channel getChannel() throws IOException, TimeoutException {
        //Create a connection factory
        ConnectionFactory factory = new ConnectionFactory();
        //Factory ip
        factory.setHost("192.168.248.10");
        //user name
        factory.setUsername("admin");
        //password
        factory.setPassword("admin");
        //create link
        Connection connection = factory.newConnection();
        //Acquisition channel
        Channel channel = connection.createChannel();

        return channel;
    }
}

  1. Create producer
package com.rabbitmq1;

import com.rabbitmq.client.Channel;
import com.rabbitmqUtils.RabbitmqUtils;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @author Naive heat
 * @create 2022-02-08 14:52
 * @desc
 **/
public class Product {
    //Send a message
    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        //Acquisition channel
        Channel channel = RabbitmqUtils.getChannel();
        //Generate a queue, do not create a switch, go to the default switch
        //1. Name
        //2. Whether the queue message is persistent (No: stored in memory, yes: stored in disk. No by default)
        //3. Whether the queue is only for one consumer. No by default
        //4. Whether to delete automatically after the last consumer disconnects.
        //5. Other parameters
        channel.queueDeclare(RabbitmqUtils.RABBITMQ_QUEUE, true, false, false, null);
        //Send a message
        String message = "this is QUEUE_P1";
        //Keep sending messages
        for (int i = 0; i < 10; i++) {
            Thread.sleep(1000);
            //1. Switch. The simple version is not considered, and the empty string is directly used, that is, the default switch
            //2. Route key. Write the queue name directly
            //3. Parameter, ignore
            //4. Message body
            channel.basicPublish("", RabbitmqUtils.RABBITMQ_QUEUE, null, (message+i).getBytes());
        }

        System.out.println("Message sent successfully");
    }
}

  1. Create consumer
package com.rabbitmq1;

import com.rabbitmq.client.*;
import com.rabbitmqUtils.RabbitmqUtils;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @author Naive heat
 * @create 2022-02-08 15:34
 * @desc
 **/
public class Consume {


    //Send a message
    public static void main(String[] args) throws IOException, TimeoutException {
        //Acquisition channel
        Channel channel = RabbitmqUtils.getChannel();
        //Callback method when the consumer fails to consume successfully
        DeliverCallback deliverCallback = (consumerTag, message) -> {
            System.out.println("Callback when consumers successfully spend" + new String(message.getBody()));
        };
        //Callback method for consumers to cancel consumption
        CancelCallback cancelCallback = consumerTag -> {
            System.out.println("Callback method for consumers to cancel consumption");
        };

        //Consumption news
        //1. Queue name
        //2. Whether to respond automatically after successful consumption
        //3. Callback when consumers successfully consume
        //4. Callback method for consumers to cancel consumption
        channel.basicConsume(RabbitmqUtils.RABBITMQ_QUEUE, true, deliverCallback, cancelCallback);
    }
}

Start the producer class and check the rabbitmq visual interface. You can find that 10 entries have been written

Start the consumer. The effect is as follows. You can see that the queue message has been consumed. Then it is successful!

ps: if an error is reported, error com rabbitmq. client. impl. Forgivingexceptionhandler - an unexpected connection driver error occurred, admin authorization is required

8, Code implementation - multiple consumers

Working principle diagram

producer

package com.rabbitmq2;

import com.rabbitmq.client.Channel;
import com.rabbitmqUtils.RabbitmqUtils;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @author Naive heat
 * @create 2022-02-08 14:52
 * @desc
 **/
public class Product {
    //Send a message
    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        //Acquisition channel
        Channel channel = RabbitmqUtils.getChannel();
        //0 is polling, 1 is unfair distribution, and greater than 1 is the preset value. The default value is 0. After prefetching, unfair distribution is carried out.
        channel.basicQos(0);
        //Generating queues,
        //1. Name
        //2. Whether the queue message is persistent (No: stored in memory, yes: stored in disk. No by default)
        //3. Whether the queue is only for one consumer. No by default
        //4. Whether to delete automatically after the last consumer disconnects.
        //5. Other parameters
        channel.queueDeclare(RabbitmqUtils.RABBITMQ_QUEUE, true, false, false, null);
        //Keep sending messages
        for (int i = 0; i < 10; i++) {
            String message="this is Product"+i;
            //1. Switch. The simple version is not considered, and the empty string can be directly used (default / nameless switch)
            //2. Route key. Write the queue name directly
            //3. Parameter, ignore
            //4. Message body
            channel.basicPublish("", RabbitmqUtils.RABBITMQ_QUEUE, null, message.getBytes());
        }

        System.out.println("Message sent successfully");
    }
}


Consumer 1

package com.rabbitmq2;

import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;
import com.rabbitmqUtils.RabbitmqUtils;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * This is a worker thread
 *
 * @author Naive heat
 * @create 2022-02-08 16:36
 * @desc
 **/
public class Consume01 {
    //receive messages
    public static void main(String[] args) throws IOException, TimeoutException {
        System.out.println("This is worker thread 1....");
        Channel channel = RabbitmqUtils.getChannel();

        //Callback method when consumers consume successfully
        DeliverCallback deliverCallback = (consumerTag, message) -> {
            System.out.println("Callback when consumers successfully spend" + new String(message.getBody()));
        };
        //Callback method for consumers to cancel consumption
        CancelCallback cancelCallback = consumerTag -> {
            System.out.println("Callback method for consumers to cancel consumption");
        };

        //Consumption news
        //1. Queue name
        //2. Whether to respond automatically after successful consumption (if yes, it is successful by default, otherwise it is required)
        //3. Callback when consumers fail to consume successfully
        //4. Callback method for consumers to cancel consumption
        channel.basicConsume(RabbitmqUtils.RABBITMQ_QUEUE, true, deliverCallback, cancelCallback);
    }
}

Consumer 2

package com.rabbitmq2;

import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;
import com.rabbitmqUtils.RabbitmqUtils;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * This is a worker thread
 *
 * @author Naive heat
 * @create 2022-02-08 16:36
 * @desc
 **/
public class Consume02 {
    //receive messages
    public static void main(String[] args) throws IOException, TimeoutException {
        System.out.println("This is worker thread 2....");
        Channel channel = RabbitmqUtils.getChannel();

        //Callback method when the consumer fails to consume successfully
        DeliverCallback deliverCallback = (consumerTag, message) -> {
            System.out.println("Callback when consumers successfully spend" + new String(message.getBody()));
        };
        //Callback method for consumers to cancel consumption
        CancelCallback cancelCallback = consumerTag -> {
            System.out.println("Callback method for consumers to cancel consumption");
        };

        //Consumption news
        //1. Queue name
        //2. Whether to respond automatically after successful consumption
        //3. Callback when consumers successfully consume
        //4. Callback method for consumers to cancel consumption
        channel.basicConsume(RabbitmqUtils.RABBITMQ_QUEUE, true, deliverCallback, cancelCallback);
    }
}

Start consumer 1 and then consumer 2 Then start the producer and you can see that the message is polled and sent to two consumers.

8, Code implementation - automatic / manual response

  1. concept
    1) Automatic response: when the message is sent from the queue to the consumer, the default consumption is successful.
    Advantages: high efficiency.
    On the one hand, if the message is successfully processed, the consumer will lose the default message. On the other hand, if the message is successfully processed, the consumer will lose the data. On the other hand, if the consumer's system performance is crossed and cannot process messages in time, it will cause message backlog, memory depletion and crash.
    2) Manual response: when a message is sent from the queue to the consumer, the consumer needs to manually confirm the message before the queue considers the consumption successful.
    Advantages: data transmission is relatively safe and operable.
    Disadvantages: low efficiency
  2. Operability in manual response environment
    1) According to the efficiency of different consumers' response messages, the queue can dynamically allocate messages to consumers
    2) For some special queue information, you can choose to reject it and put it back in the queue
  3. code implementation

producer

package com.rabbitmq3;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.MessageProperties;
import com.rabbitmqUtils.RabbitmqUtils;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @author Naive heat
 * @create 2022-02-08 14:52
 * @desc
 **/
public class Product {
    //Send a message
    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        //Acquisition channel
        Channel channel = RabbitmqUtils.getChannel();
        //Generating queues,
        //1. Name
        //2. Whether the queue message is persistent (No: stored in memory, yes: stored in disk. No by default)
        //3. Whether the queue is only for one consumer. No by default
        //4. Whether to delete automatically after the last consumer disconnects.
        //5. Other parameters
        channel.queueDeclare(RabbitmqUtils.RABBITMQ_QUEUE, true, false, false, null);
        //Keep sending messages
        for (int i = 0; i < 10; i++) {
            //Send a message
            String message = "this is Product"+i;
            //1. Switch. The simple version is not considered, and the empty string can be directly used (default / nameless switch)
            //2. Route key. Write the queue name directly
            //3. Parameter, (message persistence is effective only when the queue is enabled)
            //4. Message body
            channel.basicPublish("", RabbitmqUtils.RABBITMQ_QUEUE, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes());
        }

        System.out.println("Message sent successfully");
    }
}

Consumer 1 (accept, accept 1 every second, take 5 initially)

package com.rabbitmq3;

import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;
import com.rabbitmqUtils.RabbitmqUtils;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * This is a worker thread
 *
 * @author Naive heat
 * @create 2022-02-08 16:36
 * @desc
 **/
public class Consume01 {
    //receive messages
    public static void main(String[] args) throws IOException, TimeoutException {
        System.out.println("This is worker thread 1....");
        Channel channel = RabbitmqUtils.getChannel();
        //0 is polling, the default
        //1 is unfair distribution, that is, which consumer is efficient and which side is distributed more
        //If it is greater than 1, it is a pre value, that is, the number of messages that consumers will consume. After prefetching, unfair distribution is carried out.
        channel.basicQos(5);

        //Callback method when consumers consume successfully
        DeliverCallback deliverCallback = (consumerTag, message) -> {
            //sleep
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Callback when consumers successfully spend" + new String(message.getBody()));

            //Manual response
            //1. Message confirmation flag, 2 Batch response
            channel.basicAck(message.getEnvelope().getDeliveryTag(), false);

        };
        //Callback method for consumers to cancel consumption
        CancelCallback cancelCallback = consumerTag -> {
            System.out.println("Callback method for consumers to cancel consumption");
        };

        //Consumption news
        //1. Queue name
        //2. Whether to respond automatically after successful consumption (if yes, it is successful by default, otherwise it is required)
        //3. Callback when consumers fail to consume successfully
        //4. Callback method for consumers to cancel consumption
        channel.basicConsume(RabbitmqUtils.RABBITMQ_QUEUE, false, deliverCallback, cancelCallback);
    }
}

Consumer 2 (reject, reject one every 10s, take 2 initially)

package com.rabbitmq3;

import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;
import com.rabbitmqUtils.RabbitmqUtils;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * This is a worker thread
 *
 * @author Naive heat
 * @create 2022-02-08 16:36
 * @desc
 **/
public class Consume02 {
    //receive messages
    public static void main(String[] args) throws IOException, TimeoutException {
        System.out.println("This is worker thread 2....");
        Channel channel = RabbitmqUtils.getChannel();
        //0 is polling, 1 is unfair distribution, and greater than 1 is the preset value. The default value is 0. After prefetching, unfair distribution is carried out.
        channel.basicQos(2);

        //Callback method when consumers consume successfully
        DeliverCallback deliverCallback = (consumerTag, message) -> {
            //sleep
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Callback when consumers successfully spend" + new String(message.getBody()));

            //1. Message negative acknowledgement flag, 2 Is the message re queued
            channel.basicReject(message.getEnvelope().getDeliveryTag(), true);

        };
        //Callback method for consumers to cancel consumption
        CancelCallback cancelCallback = consumerTag -> {
            System.out.println("Callback method for consumers to cancel consumption");
        };

        //Consumption news
        //1. Queue name
        //2. Whether to respond automatically after successful consumption (if yes, it is successful by default, otherwise it is required)
        //3. Callback when consumers fail to consume successfully
        //4. Callback method for consumers to cancel consumption
        channel.basicConsume(RabbitmqUtils.RABBITMQ_QUEUE, false, deliverCallback, cancelCallback);
    }
}

You can check the rabbitmq interface

result:

9, Code implementation - three ways of message publishing confirmation

Message release confirmation means that after the producer sends the message to the Broker, if the Broker receives the message, it will give a reply to our producer. The producer receives the response to determine whether the message is sent to the Broker normally. There are three ways to confirm news release.

  1. Single confirmation is to confirm every time a message is sent. The advantage is that it is accurate, but the disadvantage is that it takes up a lot of resources and is slow. The test time of 1000 pieces of data is 1311ms
    /**
     * Single confirmation
     */
    public static void publishDg() throws IOException, TimeoutException, InterruptedException {
        //Acquisition channel
        Channel channel = RabbitmqUtils.getChannel();
        //Open release confirmation
        channel.confirmSelect();
        //start time
        long begin = System.currentTimeMillis();
        //send message
        for (int i = 0; i < 1000; i++) {
            channel.basicPublish("", RabbitmqUtils.RABBITMQ_QUEUE, MessageProperties.PERSISTENT_TEXT_PLAIN, ("message" + i).getBytes());
            //Release confirmation
            boolean flag = channel.waitForConfirms();
            if (flag) {
                System.out.println("Sent successfully");
            }
        }
        //End time
        long end = System.currentTimeMillis();
        System.out.println("Time spent on individual confirmation=" + (end - begin));
    }
  1. Batch confirmation refers to another confirmation for each batch of messages sent. The advantage is that it is faster than a single confirmation, but it cannot accurately locate the sending failure message. The test time of 1000 pieces of data is 170ms
  public static void publishPl() throws IOException, TimeoutException, InterruptedException {
        //Acquisition channel
        Channel channel = RabbitmqUtils.getChannel();
        //Open release confirmation
        channel.confirmSelect();
        //start time
        long begin = System.currentTimeMillis();
        //Batch confirmation size
        int batchSize = 100;
        //Batch sending messages and confirmation
        for (int i = 0; i < 1000; i++) {
            channel.basicPublish("", RabbitmqUtils.RABBITMQ_QUEUE, MessageProperties.PERSISTENT_TEXT_PLAIN, ("message" + i).getBytes());
            if (i % batchSize == 0) {
                channel.waitForConfirms();
            }
        }

        //End time
        long end = System.currentTimeMillis();
        System.out.println("Time spent on individual confirmation=" + (end - begin));
    }
  1. Asynchronous confirmation is to create a Map that supports high concurrency before sending, key stores message tag, values stores message, and call the listener to listen for message sending. If the callback function sends the message successfully, it will record the result according to the callback function after sending the message successfully. Send failed, call back the failed function, and display the message through Map in the failed function. Asynchronous acknowledgment has the best overall performance of all acknowledgments. The test time of 1000 pieces of data is 43ms
 public static void publishYb() throws IOException, TimeoutException, InterruptedException {
        //Acquisition channel
        Channel channel = RabbitmqUtils.getChannel();
        //Open release confirmation
        channel.confirmSelect();
        //start time
        long begin = System.currentTimeMillis();


        //A thread safe and orderly hash table, suitable for high concurrency
        //1. Associate serial number with message
        //2. Easily delete entries in batch as long as the serial number is given
        //3. Support high concurrency
        ConcurrentSkipListMap<Long, String> concurrentSkipListMap = new ConcurrentSkipListMap<>();

        //--------------------Listener--------------------------
        //Message confirmation success callback function
        //1. Mark of message, 2 Batch operation
        ConfirmCallback ackCallback = (deliveryTag, multiple) -> {
            //Message acceptance processing
            if (multiple) {
                //batch
                ConcurrentNavigableMap<Long, String> confirmd = concurrentSkipListMap.headMap(deliveryTag);
                confirmd.clear();
            } else {
                //Non batch
                concurrentSkipListMap.remove(deliveryTag);
            }

            System.out.println("Confirmed message:" + deliveryTag);
        };

        //Message confirmation failure callback function
        //1. Mark of message, 2 Batch operation
        ConfirmCallback nackCallback = (deliveryTag, multiple) -> {
            //The message was not accepted for processing
            String message = concurrentSkipListMap.get(deliveryTag);
            System.out.println("Unacknowledged message:" + deliveryTag + ":" + message);
        };

        //Message listener, listening for failure and success messages
        channel.addConfirmListener(ackCallback, nackCallback);
        //Batch sending messages and confirmation
        for (int i = 0; i < 1000; i++) {
            String message = ("message" + i);
            channel.basicPublish("", RabbitmqUtils.RABBITMQ_QUEUE, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes());
            //Record messages sent
            concurrentSkipListMap.put(channel.getNextPublishSeqNo(), message);
        }

        //End time
        long end = System.currentTimeMillis();
        System.out.println("Time spent on individual confirmation=" + (end - begin));
        System.out.println(concurrentSkipListMap.size());

    }

10, Code implementation - switch

As mentioned earlier, in fact, the producer sends messages directly to the switch, and then the switch assigns them to the queue according to relevant rules. According to the allocation rules, the common base switches are: direct switch, topic switch, topic switch, Headers switch, etc.
ps: because I use the same switch here. If the same switch is used and the configuration is modified, the original switch needs to be deleted, otherwise an error will be reported.

  1. Switch mode I fanout
    This mode is the same as broadcasting, that is, all messages sent to the switch will be sent to all queues of the switch. The code is as follows:

producer

package com.rabbitmq5;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.MessageProperties;
import com.rabbitmqUtils.RabbitmqUtils;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @author Naive heat
 * @create 2022-02-08 14:52
 * @desc
 **/
public class Product {
    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        //Acquisition channel
        Channel channel = RabbitmqUtils.getChannel();
        //Declare a switch
        channel.exchangeDeclare(RabbitmqUtils.RABBITMQ_EXCHANGE, "fanout");

        for (int i = 0; i < 10; i++) {
            String message = "Messages sent" + i;
            //1. Switch. The simple version is not considered, and the empty string can be directly used (default / nameless switch)
            //2. Route key. Write the queue name directly
            //3. Parameter, (message persistence)
            //4. Message body
            channel.basicPublish(RabbitmqUtils.RABBITMQ_EXCHANGE, "", MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes());
        }
    }
}

Consumer 1

package com.rabbitmq5;

import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;
import com.rabbitmqUtils.RabbitmqUtils;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @author Naive heat
 * @create 2022-02-08 14:52
 * @desc
 **/
public class Consume01 {
    //receive messages
    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        //Acquisition channel
        Channel channel = RabbitmqUtils.getChannel();
        //Declare a switch
        channel.exchangeDeclare(RabbitmqUtils.RABBITMQ_EXCHANGE, "fanout");
        //Declare a temporary queue
        String queueName = channel.queueDeclare().getQueue();
        //Binding switches and queues
        channel.queueBind(queueName, RabbitmqUtils.RABBITMQ_EXCHANGE, "");


        //Callback method when consumers consume successfully
        DeliverCallback deliverCallback = (consumerTag, message) -> {
            System.out.println("Callback when consumers successfully spend" + new String(message.getBody()));
        };
        //Callback method for consumers to cancel consumption
        CancelCallback cancelCallback = consumerTag -> {
            System.out.println("Callback method for consumers to cancel consumption");
        };

        //Consumption news
        //1. Queue name
        //2. Whether to respond automatically after successful consumption (if yes, it is successful by default, otherwise it is required)
        //3. Callback when consumers fail to consume successfully
        //4. Callback method for consumers to cancel consumption
        channel.basicConsume(queueName, true, deliverCallback, cancelCallback);

    }
}

Consumer 2:

package com.rabbitmq5;

import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;
import com.rabbitmqUtils.RabbitmqUtils;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @author Naive heat
 * @create 2022-02-08 14:52
 * @desc
 **/
public class Consume02 {
    //Send a message
    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        //Acquisition channel
        Channel channel = RabbitmqUtils.getChannel();
        //Declare a switch
        channel.exchangeDeclare(RabbitmqUtils.RABBITMQ_EXCHANGE, "fanout");
        //Declare a temporary queue
        String queueName = channel.queueDeclare().getQueue();
        //Binding switches and queues
        channel.queueBind(queueName, RabbitmqUtils.RABBITMQ_EXCHANGE, "");


        //Callback method when consumers consume successfully
        DeliverCallback deliverCallback = (consumerTag, message) -> {
            System.out.println("Callback when consumers successfully spend" + new String(message.getBody()));
        };
        //Callback method for consumers to cancel consumption
        CancelCallback cancelCallback = consumerTag -> {
            System.out.println("Callback method for consumers to cancel consumption");
        };

        //Consumption news
        //1. Queue name
        //2. Whether to respond automatically after successful consumption (if yes, it is successful by default, otherwise it is required)
        //3. Callback when consumers fail to consume successfully
        //4. Callback method for consumers to cancel consumption
        channel.basicConsume(queueName, true, deliverCallback, cancelCallback);

    }
}

result


2. Switch mode direct
Compared with fanout, this method increases certain restrictions, that is, messages can only be sent to the queue of the fixed rountKey of the switch. The code is as follows:
producer:

package com.rabbitmq6;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.MessageProperties;
import com.rabbitmqUtils.RabbitmqUtils;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @author Naive heat
 * @create 2022-02-08 14:52
 * @desc
 **/
public class Product {
    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        //Acquisition channel
        Channel channel = RabbitmqUtils.getChannel();
        //Declare a switch
//        channel.exchangeDeclare(RabbitmqUtils.RABBITMQ_EXCHANGE, "direct");

        for (int i = 0; i < 10; i++) {
            String message = "Messages sent" + i;
            //1. Switch. The simple version is not considered, and the empty string can be directly used (default / nameless switch)
            //2. Route key. Write the queue name directly
            //3. Parameter, (message persistence)
            //4. Message body
            channel.basicPublish(RabbitmqUtils.RABBITMQ_EXCHANGE, "error", MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes());
        }
    }
}

Consumer 1:

package com.rabbitmq6;

import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;
import com.rabbitmqUtils.RabbitmqUtils;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @author Naive heat
 * @create 2022-02-08 14:52
 * @desc
 **/
public class Consume01 {
    //receive messages
    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        //Acquisition channel
        Channel channel = RabbitmqUtils.getChannel();
        //Declare a switch
        channel.exchangeDeclare(RabbitmqUtils.RABBITMQ_EXCHANGE, "direct");
        //Declare a temporary queue
        String queueName = channel.queueDeclare().getQueue();
        //Binding switches and queues
        channel.queueBind(queueName, RabbitmqUtils.RABBITMQ_EXCHANGE, "info");
        channel.queueBind(queueName, RabbitmqUtils.RABBITMQ_EXCHANGE, "warning");


        //Callback method when consumers consume successfully
        DeliverCallback deliverCallback = (consumerTag, message) -> {
            System.out.println("Callback when consumers successfully spend" + new String(message.getBody()));
        };
        //Callback method for consumers to cancel consumption
        CancelCallback cancelCallback = consumerTag -> {
            System.out.println("Callback method for consumers to cancel consumption");
        };

        //Consumption news
        //1. Queue name
        //2. Whether to respond automatically after successful consumption (if yes, it is successful by default, otherwise it is required)
        //3. Callback when consumers fail to consume successfully
        //4. Callback method for consumers to cancel consumption
        channel.basicConsume(queueName, true, deliverCallback, cancelCallback);
 		System.out.println("queue info/warning wait for...");
    }
}

Consumer 2

package com.rabbitmq6;

import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;
import com.rabbitmqUtils.RabbitmqUtils;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @author Naive heat
 * @create 2022-02-08 14:52
 * @desc
 **/
public class Consume01 {
    //receive messages
    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        //Acquisition channel
        Channel channel = RabbitmqUtils.getChannel();
        //Declare a switch
        channel.exchangeDeclare(RabbitmqUtils.RABBITMQ_EXCHANGE, "direct");
        //Declare a temporary queue
        String queueName = channel.queueDeclare().getQueue();
        //Binding switches and queues
        channel.queueBind(queueName, RabbitmqUtils.RABBITMQ_EXCHANGE, "info");
        channel.queueBind(queueName, RabbitmqUtils.RABBITMQ_EXCHANGE, "warning");


        //Callback method when consumers consume successfully
        DeliverCallback deliverCallback = (consumerTag, message) -> {
            System.out.println("Callback when consumers successfully spend" + new String(message.getBody()));
        };
        //Callback method for consumers to cancel consumption
        CancelCallback cancelCallback = consumerTag -> {
            System.out.println("Callback method for consumers to cancel consumption");
        };

        //Consumption news
        //1. Queue name
        //2. Whether to respond automatically after successful consumption (if yes, it is successful by default, otherwise it is required)
        //3. Callback when consumers fail to consume successfully
        //4. Callback method for consumers to cancel consumption
        channel.basicConsume(queueName, true, deliverCallback, cancelCallback);
		System.out.println("queue error wait for...");
    }
}
       



3. topic of switch mode
The direct mode mentioned above is actually the absolute matching of rountkey. topic is the fuzzy matching of roundkey.
*(asterisk) represents a word
#(pound sign) can replace zero or more words
The code is as follows:
producer

package com.rabbitmq7;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.MessageProperties;
import com.rabbitmqUtils.RabbitmqUtils;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @author Naive heat
 * @create 2022-02-08 14:52
 * @desc
 **/
public class Product {
    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        //Acquisition channel
        Channel channel = RabbitmqUtils.getChannel();
        //Declare a switch
        channel.exchangeDeclare(RabbitmqUtils.RABBITMQ_EXCHANGE, "topic");

        for (int i = 0; i < 10; i++) {
            String message = "Messages sent" + i;
            //1. Switch. The simple version is not considered, and the empty string can be directly used (default / nameless switch)
            //2. Route key. Write the queue name directly
            //3. Parameter, (message persistence)
            //4. Message body
            channel.basicPublish(RabbitmqUtils.RABBITMQ_EXCHANGE, "queue.queue.queue11", MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes());
        }
    }
}

Consumer 1

package com.rabbitmq7;

import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;
import com.rabbitmqUtils.RabbitmqUtils;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @author Naive heat
 * @create 2022-02-08 14:52
 * @desc
 **/
public class Consume01 {
    //receive messages
    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        //Acquisition channel
        Channel channel = RabbitmqUtils.getChannel();
        //Declare a switch
        channel.exchangeDeclare(RabbitmqUtils.RABBITMQ_EXCHANGE, "topic");
        //Declare a temporary queue
        String queueName = channel.queueDeclare().getQueue();
        //Binding switches and queues
        channel.queueBind(queueName, RabbitmqUtils.RABBITMQ_EXCHANGE, "*.queue.*");


        //Callback method when consumers consume successfully
        DeliverCallback deliverCallback = (consumerTag, message) -> {
            System.out.println("Callback when consumers successfully spend" + new String(message.getBody()));
        };
        //Callback method for consumers to cancel consumption
        CancelCallback cancelCallback = consumerTag -> {
            System.out.println("Callback method for consumers to cancel consumption");
        };

        //Consumption news
        //1. Queue name
        //2. Whether to respond automatically after successful consumption (if yes, it is successful by default, otherwise it is required)
        //3. Callback when consumers fail to consume successfully
        //4. Callback method for consumers to cancel consumption
        channel.basicConsume(queueName, true, deliverCallback, cancelCallback);
        System.out.println("consumer|*.queue.*|Waiting....");
    }
}

Consumer 2

package com.rabbitmq7;

import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;
import com.rabbitmqUtils.RabbitmqUtils;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @author Naive heat
 * @create 2022-02-08 14:52
 * @desc
 **/
public class Consume02 {
    //receive messages
    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        //Acquisition channel
        Channel channel = RabbitmqUtils.getChannel();
        //Declare a switch
        channel.exchangeDeclare(RabbitmqUtils.RABBITMQ_EXCHANGE, "topic");
        //Declare a temporary queue
        String queueName = channel.queueDeclare().getQueue();
        //Binding switches and queues
        channel.queueBind(queueName, RabbitmqUtils.RABBITMQ_EXCHANGE, "queue.*.*");


        //Callback method when consumers consume successfully
        DeliverCallback deliverCallback = (consumerTag, message) -> {
            System.out.println("Callback when consumers successfully spend" + new String(message.getBody()));
        };
        //Callback method for consumers to cancel consumption
        CancelCallback cancelCallback = consumerTag -> {
            System.out.println("Callback method for consumers to cancel consumption");
        };

        //Consumption news
        //1. Queue name
        //2. Whether to respond automatically after successful consumption (if yes, it is successful by default, otherwise it is required)
        //3. Callback when consumers fail to consume successfully
        //4. Callback method for consumers to cancel consumption
        channel.basicConsume(queueName, true, deliverCallback, cancelCallback);
        System.out.println("consumer|queue.*.*|Waiting....");
    }
}

effect

11, Code implementation - priority queue

The consumption order of the queue is generally first in first out. However, in some order businesses, we need to give vip users the special permission to place an order and ship first. At this time, we need to use the priority queue.
Principle: in the original FIFO logic, the priority is given to the queue. The final order is as follows:
High priority – > low priority – > no note priority
ps: the priority range is 0-255
producer

package com.rabbitmq12;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmqUtils.RabbitmqUtils;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeoutException;

/**
 * @author Naive heat
 * @create 2022-02-08 14:52
 * @desc
 **/
public class Product {
    //Queue name
    public static final String ORDER_QUEUE = "ORDER_QUEUE";

    //Send a message
    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        //Acquisition channel
        Channel channel = RabbitmqUtils.getChannel();
        //parameter
        Map<String, Object> argument = new HashMap<>();
        argument.put("x-max-priority", 10);//Set the priority range 0-10, and the official allowable value is 0-255. Setting too much will waste memory

        //Generating queues,
        //Do not create a switch, go to the default switch
        //1. Name
        //2. Whether the queue message is persistent (No: stored in memory, yes: stored in disk. No by default)
        //3. Whether the queue is only for one consumer. No by default
        //4. Whether to delete automatically after the last consumer disconnects.
        //5. Other parameters
        channel.queueDeclare(ORDER_QUEUE, true, false, false, argument);
        //Send a message
        String message = "this is QUEUE_P";
        //Keep sending messages
        for (int i = 0; i < 10; i++) {
            //1. Switch. The simple version is not considered, and the empty string can be directly used (default / nameless switch)
            //2. Route key. Write the queue name directly
            //3. Parameter, ignore
            //4. Message body
            if (i == 5) {
                AMQP.BasicProperties properties = new AMQP.BasicProperties().builder().priority(5).build();
                channel.basicPublish("", ORDER_QUEUE, properties, (message + i).getBytes());
            } else {
                channel.basicPublish("", ORDER_QUEUE, null, (message + i).getBytes());
            }

        }

        System.out.println("Message sent successfully");
    }
}

consumer

package com.rabbitmq12;

import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;
import com.rabbitmqUtils.RabbitmqUtils;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @author Naive heat
 * @create 2022-02-08 15:34
 * @desc
 **/
public class Consume {
    //Queue name
    public static final String ORDER_QUEUE = "ORDER_QUEUE";

    //Send a message
    public static void main(String[] args) throws IOException, TimeoutException {
        //Acquisition channel
        Channel channel = RabbitmqUtils.getChannel();
        //Callback method when the consumer fails to consume successfully
        DeliverCallback deliverCallback = (consumerTag, message) -> {
            System.out.println("Callback when consumers successfully spend" + new String(message.getBody()));
        };
        //Callback method for consumers to cancel consumption
        CancelCallback cancelCallback = consumerTag -> {
            System.out.println("Callback method for consumers to cancel consumption");
        };

        //Consumption news
        //1. Queue name
        //2. Whether to respond automatically after successful consumption
        //3. Callback when consumers successfully consume
        //4. Callback method for consumers to cancel consumption
        channel.basicConsume(ORDER_QUEUE, true, deliverCallback, cancelCallback);
    }
}

Test, start the producer, and then start the consumer

12, Code implementation - dead letter queue

Dead letter refers to information that cannot be consumed. These messages cannot be consumed because of some reasons such as network timeout, and become dead letter messages. Therefore, in order to ensure that these data are not lost, there is a dead letter queue to process dead letter messages.
Working drawing:

The code is as follows:
Generated by:

package com.rabbitmq8;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.MessageProperties;
import com.rabbitmqUtils.RabbitmqUtils;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @author Naive heat
 * @create 2022-02-08 14:52
 * @desc
 **/
public class Product {
    //Normal switch
    public static String NORMAL_EXCHANGE = "NORMAL_EXCHANGE";

    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        //Acquisition channel
        Channel channel = RabbitmqUtils.getChannel();
        //Declare a switch (duplicate declaration is not required)
        //channel.exchangeDeclare(NORMAL_EXCHANGE, "direct");

        //Set the ttl time to 10s, and enter the dead letter queue when it expires
        AMQP.BasicProperties properties = new AMQP.BasicProperties().builder().expiration("10000").build();

        //Send dead letter message
        for (int i = 0; i < 10; i++) {
            String message = "Messages sent" + i;
            //1. Switch. The simple version is not considered, and the empty string can be directly used (default / nameless switch)
            //2. Route key. Write the queue name directly
            //3. Parameter, (message persistence)
            //4. Message body
            channel.basicPublish(NORMAL_EXCHANGE, "normalQueue", properties, message.getBytes());
        }
    }
}

Consumer (normal queue)

package com.rabbitmq8;

import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;
import com.rabbitmqUtils.RabbitmqUtils;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeoutException;

/**
 * @author Naive heat
 * @create 2022-02-08 14:52
 * @desc
 **/
public class Consume01 {
    //Normal switch
    public static String NORMAL_EXCHANGE = "NORMAL_EXCHANGE";
    //Dead letter switch
    public static String DEAD_EXCHANGE = "DEAD_EXCHANGE";
    //Normal queue
    public static String NORMAL_QUEUE = "NORMAL_QUEUE";
    //Dead letter queue
    public static String DEAD_QUEUE = "DEAD_QUEUE";

    //receive messages
    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        //Acquisition channel
        Channel channel = RabbitmqUtils.getChannel();
        //Declare normal and dead letter switches
        channel.exchangeDeclare(NORMAL_EXCHANGE, "direct");
        channel.exchangeDeclare(DEAD_EXCHANGE, "direct");

        //Declare dead letter queue
        channel.queueDeclare(DEAD_QUEUE, false, false, false, null);


        //Set parameters
        Map<String, Object> arguments = new HashMap<>();
        //Set up dead letter switch
        arguments.put("x-dead-letter-exchange", DEAD_EXCHANGE);
        //Set dead letter RoutingKey
        arguments.put("x-dead-letter-routing-key", "deadQueue");
        //Set normal queue length
        arguments.put("x-max-length", 6);
        //Set the expiration time, 10s (generally not set here, but configured on the producer side, so that the sub expiration time can be changed at will by the producer)
        //arguments.put("x-message-ttl", "10000");
        //Declare normal queue
        channel.queueDeclare(NORMAL_QUEUE, false, false, false, arguments);

        //Binding common switches and queues
        channel.queueBind(NORMAL_QUEUE, NORMAL_EXCHANGE, "normalQueue");
        //Binding dead letter switch and queue
        channel.queueBind(DEAD_QUEUE, DEAD_EXCHANGE, "deadQueue");


        //Callback method when consumers consume successfully
        DeliverCallback deliverCallback = (consumerTag, message) -> {
            System.out.println("refuse");
            //Reject and do not put it back in the queue
            channel.basicReject(message.getEnvelope().getDeliveryTag(), false);
        };
        //Callback method for consumers to cancel consumption
        CancelCallback cancelCallback = consumerTag -> {
            System.out.println("Callback method for consumers to cancel consumption");
        };

        //Consumption news
        channel.basicConsume(NORMAL_QUEUE, false, deliverCallback, cancelCallback);
        System.out.println("Normal queue preparation consumption message......");
    }
}

Consumer 2 (dead letter queue)

package com.rabbitmq8;

import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;
import com.rabbitmqUtils.RabbitmqUtils;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeoutException;

/**
 * @author Naive heat
 * @create 2022-02-08 14:52
 * @desc
 **/
public class Consume02 {
    //Dead letter queue
    public static String DEAD_QUEUE = "DEAD_QUEUE";

    //receive messages
    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        //Acquisition channel
        Channel channel = RabbitmqUtils.getChannel();

        //Callback method when consumers consume successfully
        DeliverCallback deliverCallback = (consumerTag, message) -> {
            System.out.println("Callback when consumers successfully spend" + new String(message.getBody()));
        };
        //Callback method for consumers to cancel consumption
        CancelCallback cancelCallback = consumerTag -> {
            System.out.println("Callback method for consumers to cancel consumption");
        };

        //Consumption news
        channel.basicConsume(DEAD_QUEUE, true, deliverCallback, cancelCallback);
        System.out.println("Dead letter queue ready to consume messages......");
    }
}

Test 1: first run the dead letter queue, and then run the producer. Since the produced messages are not consumed, the messages will automatically enter the dead letter queue after timeout

Test 2: run the dead letter queue and normal queue, and then run the producer. Since the production message is rejected, the message will automatically enter the dead letter queue when it times out

13, Code implementation - delay queue

Delay queue: the elements in the delay queue are processed after reaching the specified time. If the order function, if payment is not made within the specified time, the order will be cancelled.
schematic diagram:

Because our subsequent rabbitmq must run in the springboot framework, we need to integrate springboot here.

  1. Configure in yml configuration file
spring:
  rabbitmq:
    host: 192.168.248.10
    port: 5672
    username: admin
    password: admin
    #Switch confirmation interface
    publisher-confirms: true
  1. Add configuration class
package com.rabbitmq9;

import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * @author Naive heat
 * @create 2022-02-10 10:09
 * @desc
 **/
@Configuration
public class Config {
    //General exchange
    public static final String X_EXCHANGE = "X";
    //Dead letter switch
    public static final String Y_DEAD_LETTER_EXCHANGE = "Y";
    //Common queue name
    public static final String QUEUE_A = "QA";
    public static final String QUEUE_B = "QB";
    public static final String QUEUE_C = "QC";
    //Dead letter queue name
    public static final String DEAD_LETTER_QUEUE = "QD";

    //Declare xExchange alias
    @Bean("xExchange")
    public DirectExchange xExchange() {
        return new DirectExchange(X_EXCHANGE);
    }

    //Declare yExchange alias
    @Bean("yExchange")
    public DirectExchange yExchange() {
        return new DirectExchange(Y_DEAD_LETTER_EXCHANGE);
    }

    //Declare the normal queue A ttl as 10s
    @Bean("queueA")
    public Queue queuA() {
        Map<String, Object> argument = new HashMap<>();
        //Set up dead letter switch
        argument.put("x-dead-letter-exchange", Y_DEAD_LETTER_EXCHANGE);
        //Set dead letter RoutingKey
        argument.put("x-dead-letter-routing-key", "YD");
        //Set ttl,10s
        argument.put("x-message-ttl", 10000);
        //Create queue
        return QueueBuilder.durable(QUEUE_A).withArguments(argument).build();
    }

    //Declare the normal queue B ttl as 10s
    @Bean("queueB")
    public Queue queuB() {
        Map<String, Object> argument = new HashMap<>();
        //Set up dead letter switch
        argument.put("x-dead-letter-exchange", Y_DEAD_LETTER_EXCHANGE);
        //Set dead letter RoutingKey
        argument.put("x-dead-letter-routing-key", "YD");
        //Set ttl,40s
        argument.put("x-message-ttl", 40000);
        //Create queue
        return QueueBuilder.durable(QUEUE_B).withArguments(argument).build();
    }

    //Declare that the common queue C ttl is determined by the producer
    @Bean("queueC")
    public Queue queuC() {
        Map<String, Object> argument = new HashMap<>();
        //Set up dead letter switch
        argument.put("x-dead-letter-exchange", Y_DEAD_LETTER_EXCHANGE);
        //Set dead letter RoutingKey
        argument.put("x-dead-letter-routing-key", "YD");
        //Create queue
        return QueueBuilder.durable(QUEUE_C).withArguments(argument).build();
    }

    //Dead letter queue
    @Bean("queueD")
    public Queue queuD() {
        //Create queue
        return QueueBuilder.durable(DEAD_LETTER_QUEUE).build();
    }

    //Bind queue A
    @Bean
    public Binding queueABindingX(@Qualifier("queueA") Queue queueA, @Qualifier("xExchange") DirectExchange xExchange) {
        return BindingBuilder.bind(queueA).to(xExchange).with("XA");
    }

    //Bind queue B
    @Bean
    public Binding queueBBindingX(@Qualifier("queueB") Queue queueB, @Qualifier("xExchange") DirectExchange xExchange) {
        return BindingBuilder.bind(queueB).to(xExchange).with("XB");
    }

    //Bind queue C
    @Bean
    public Binding queueCBindingX(@Qualifier("queueC") Queue queueC, @Qualifier("xExchange") DirectExchange xExchange) {
        return BindingBuilder.bind(queueC).to(xExchange).with("XC");
    }

    //Bind queue D
    @Bean
    public Binding queueDBindingY(@Qualifier("queueD") Queue queueD, @Qualifier("yExchange") DirectExchange yExchange) {
        return BindingBuilder.bind(queueD).to(yExchange).with("YD");
    }




}

  1. Add production message class
package com.rabbitmq9;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author Naive heat
 * @create 2022-02-10 15:03
 * @desc
 **/
@Slf4j
@RestController
@RequestMapping("/ttl")
public class SendMessageController {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @GetMapping("/sendMsg/{message}")
    public void sendMessage(@PathVariable String message) {
        log.info("send message");
        rabbitTemplate.convertAndSend("X", "XA", "Message from 10 s of ttl: " + message);
        rabbitTemplate.convertAndSend("X", "XB", "Message from 40 s of ttl: " + message);

    }

    @GetMapping("/sendExpireMsg/{message}/{ttlTime}")
    public void sendExpireMsg(@PathVariable String message, @PathVariable String ttlTime) {
        log.info("Send timing message");
        rabbitTemplate.convertAndSend("X", "XC", "Message from timed message:" + message, msg -> {
            //When sending messages, the delay is extended
            msg.getMessageProperties().setExpiration(ttlTime);
            return msg;
        });

    }
}

  1. Add consumer class
package com.rabbitmq9;

import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * Queue ttl consumers
 *
 * @author Naive heat
 * @create 2022-02-10 16:00
 * @desc
 **/
@Slf4j
@Component
public class Consume {
    //receive messages
    @RabbitListener(queues = Config.DEAD_LETTER_QUEUE)
    public void receiveD(Message msg, Channel channel) {
        String message = new String(msg.getBody());
        log.info("Delay queue message received:" + message);
    }
}

Test 1: http://localhost:8090/ttl/sendMsg/hahaha

Test 2: http://localhost:8090/ttl/sendExpireMsg/5555/100

Test 3: send two addresses continuously. It can be seen that delayed messages need to be queued, so they can't be sent first. It's a disadvantage. You can use plug-ins to overcome this problem.
http://localhost:8090/ttl/sendExpireMsg/5555/10000
http://localhost:8090/ttl/sendExpireMsg/558885/1000

14, Code implementation - RabbitMQ plug-in implements delay queue

Installation tutorial

  1. Download: https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases/tag/v3.8.0
  2. Put the plug-in in: / usr/lib/rabbitmq/lib/rabbitmq_server-3.8.8/plugins
  3. Enter the directory: cd /usr/lib/rabbitmq/lib/rabbitmq_server-3.8.8/plugins
  4. Installation: rabbitmq plugins enable rabbitmq_ delayed_ message_ exchange
  5. Restart: server restart BBQ

    working principle:

    The code is as follows
    Configuration class
package com.rabbitmq10;

import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.CustomAutowireConfigurer;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * @author Naive heat
 * @create 2022-02-10 10:09
 * @desc
 **/
@Configuration
public class DelayConfig {
    //queue
    public static final String DELAY_QUEUE = "DELAY_QUEUE";
    //Switch
    public static final String DELAY_EXCHANGE = "DELAY_EXCHANGE";
    //routingKey
    public static final String DELAY_ROUNTING_KEY = "DELAY_ROUNTING_KEY";


    //Declaration switch
    @Bean
    public CustomExchange delayEchange() {
        Map<String, Object> arguments = new HashMap<>();
        arguments.put("x-delayed-type", "direct");
        //1. Switch name
        //2. Switch type
        //3. Is persistence needed
        //4. Whether to delete automatically
        //5. Other parameters
        return new CustomExchange(DELAY_EXCHANGE, "x-delayed-message", true, false, arguments);
    }


    //Declaration queue
    @Bean
    public Queue delayQueue() {
        //Create queue
        return new Queue(DELAY_QUEUE);
    }


    //Bind queue
    @Bean
    public Binding delayBindingQueue(@Qualifier("delayQueue") Queue delayQueue, @Qualifier("delayEchange") CustomExchange delayEchange) {
        return BindingBuilder.bind(delayQueue).to(delayEchange).with("DELAY_ROUNTING_KEY").noargs();
    }

}

consumer

package com.rabbitmq10;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * Queue ttl consumers
 *
 * @author Naive heat
 * @create 2022-02-10 16:00
 * @desc
 **/
@Slf4j
@Component
public class DelayConsume {
    //receive messages
    @RabbitListener(queues = DelayConfig.DELAY_QUEUE)
    public void receiveDelay(Message msg) {

        String message = new String(msg.getBody());
        log.info("Received plug-in delay queue message:" + message);
    }
}

Send message class

package com.rabbitmq10;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author Naive heat
 * @create 2022-02-10 15:03
 * @desc
 **/
@Slf4j
@RestController
@RequestMapping("/delayed")
public class SendDelayMessageController {

    @Autowired
    private RabbitTemplate rabbitTemplate;


    @GetMapping("/sendExpireMsg/{message}/{ttlTime}")
    public void sendExpireMsg(@PathVariable String message, @PathVariable Integer ttlTime) {
        log.info("Send timing message");
        rabbitTemplate.convertAndSend(DelayConfig.DELAY_EXCHANGE, DelayConfig.DELAY_ROUNTING_KEY, "Message from timed message:" + message, msg -> {
            //When sending a message, the delay time is long
            msg.getMessageProperties().setDelay(ttlTime);
            return msg;
        });

    }
}

Test: execute the following two addresses in turn. It can be found that those with short delay time will execute first without queuing
http://localhost:8090/delayed/sendExpireMsg/10000/10000
http://localhost:8090/delayed/sendExpireMsg/500/500

15, Code implementation - release confirmation advanced

schematic diagram

configuration file

spring:
  rabbitmq:
    host: 192.168.248.10
    port: 5672
    username: admin
    password: admin
    #Switch confirmation interface
    publisher-confirms: true
    #New version: spring rabbitmq. publisher-confirm-type=correlated
    #Route fallback messages to producers
    publisher-returns: true

Send message class

package com.rabbitmq11;

import com.rabbitmq10.DelayConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.CorrelationDataPostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author Naive heat
 * @create 2022-02-10 15:03
 * @desc
 **/
@Slf4j
@RestController
@RequestMapping("/confirm")
public class SendConfirmMessageController {

    @Autowired
    private RabbitTemplate rabbitTemplate;


    @GetMapping("/sendMsgToBadExchange/{message}")
    public void sendMsgToBadExchange(@PathVariable String message) {
        //Class, which can be accepted when the queue receives messages
        CorrelationData correlationData = new CorrelationData("1");
        //send message
        rabbitTemplate.convertAndSend(ConfirmConfig.CONFIRM_EXCHANGE + "bad", ConfirmConfig.CONFIRM_ROUNTING_KEY, "Message from timed message:" + message, correlationData);
        log.info("send message");
    }

    @GetMapping("/sendMsgToBadRounting/{message}")
    public void sendMsgToBadRounting(@PathVariable String message) {
        //Class, which can be accepted when the queue receives messages
        CorrelationData correlationData = new CorrelationData("1");
        //send message
        rabbitTemplate.convertAndSend(ConfirmConfig.CONFIRM_EXCHANGE, ConfirmConfig.CONFIRM_ROUNTING_KEY + "bad", "Message from timed message:" + message, correlationData);
        log.info("send message");
    }

    @GetMapping("/sendMsg/{message}")
    public void sendMsg(@PathVariable String message) {
        //Class, which can be accepted when the queue receives messages
        CorrelationData correlationData = new CorrelationData("1");
        //send message
        rabbitTemplate.convertAndSend(ConfirmConfig.CONFIRM_EXCHANGE, ConfirmConfig.CONFIRM_ROUNTING_KEY , "Message from timed message:" + message, correlationData);
        log.info("send message");
    }

}

Configuration class

package com.rabbitmq11;

import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * Release confirmation
 *
 * @author Naive heat
 * @create 2022-02-10 10:09
 * @desc
 **/
@Configuration
public class ConfirmConfig {
    //queue
    public static final String CONFIRM_QUEUE = "CONFIRM_QUEUE";
    //Switch
    public static final String CONFIRM_EXCHANGE = "CONFIRM_EXCHANGE";
    //routingKey
    public static final String CONFIRM_ROUNTING_KEY = "CONFIRM_ROUNTING_KEY";
    //Backup switch
    public static final String BACKUP_EXCHANGE = "BACKUP_EXCHANGE";
    //Backup queue
    public static final String BACKUP_QUEUE = "BACKUP_QUEUE";
    //Alarm queue
    public static final String WARNING_QUEUE = "WARNING_QUEUE";


    //Declaration switch
    //Because the previous switch is used here, the original switch needs to be deleted to take effect
    @Bean
    public DirectExchange confirmEchange() {
        return (DirectExchange) ExchangeBuilder.directExchange(CONFIRM_EXCHANGE).durable(true).withArgument("alternate-exchange", BACKUP_EXCHANGE).build();
    }

    //Declare backup switch
    @Bean
    public FanoutExchange backupEchange() {
        return new FanoutExchange(BACKUP_EXCHANGE);
    }


    //Declaration queue
    @Bean
    public Queue confirmQueue() {
        //Create queue
        return new Queue(CONFIRM_QUEUE);
    }

    //Declare backup queue
    @Bean
    public Queue backupQueue() {
        //Create queue
        return new Queue(BACKUP_QUEUE);
    }

    //Declare alarm queue
    @Bean
    public Queue warningQueue() {
        //Create queue
        return new Queue(WARNING_QUEUE);
    }


    //Bind queue
    @Bean
    public Binding confirmBindingQueue(@Qualifier("confirmQueue") Queue confirmQueue, @Qualifier("confirmEchange") DirectExchange confirmEchange) {
        return BindingBuilder.bind(confirmQueue).to(confirmEchange).with(CONFIRM_ROUNTING_KEY);
    }

    //Bind backup queue
    @Bean
    public Binding backupBindingQueue(@Qualifier("backupQueue") Queue backupQueue, @Qualifier("backupEchange") FanoutExchange backupEchange) {
        return BindingBuilder.bind(backupQueue).to(backupEchange);
    }

    //Bind alarm queue
    @Bean
    public Binding warningBindingQueue(@Qualifier("warningQueue") Queue warningQueue, @Qualifier("backupEchange") FanoutExchange backupEchange) {
        return BindingBuilder.bind(warningQueue).to(backupEchange);
    }

}

Alarm configuration class

package com.rabbitmq11;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * Callback interface
 *
 * @author Naive heat
 * @create 2022-02-11 15:25
 * @desc
 **/
@Component
@Slf4j
public class CallBack implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    //injection
    @PostConstruct
    private void init() {
        //injection
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnCallback(this);
    }

    /**
     * Switch callback method (for whether the switch successfully receives messages)
     * 1.The messaging switch received a callback
     * 1.1 correlationData Save the id and related information of the callback message
     * 1.2 The switch receives the message ack=true
     * 1.3 call null
     * 2. The messaging switch failed a callback
     * 2.1 correlationData Save the id and related information of the callback message
     * 2.2 The switch receives the message ack=false
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        String id = correlationData != null ? correlationData.getId() : "";
        if (ack) {
            System.out.println("The switch accepted successfully");
        } else {
            System.out.println("Switch acceptance failed");
        }

    }

    /**
     * When the message cannot reach the destination, it is returned to the producer
     *
     * @param message    news
     * @param replayCode Failure code
     * @param replayText Failure reason
     * @param exchanges  Switch
     * @param routingKey route
     */
    @Override
    public void returnedMessage(Message message, int replayCode, String replayText, String exchanges, String routingKey) {
        System.out.println("Queue acceptance failed");
        System.out.println("Message:" + message + ";Message code:" + replayCode + ";reason:" + replayText + ";Switch:" + exchanges + ";route:" + routingKey);
    }
}

Normal consumer

package com.rabbitmq11;

import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * Release confirmation
 *
 * @author Naive heat
 * @create 2022-02-10 10:09
 * @desc
 **/
@Configuration
public class ConfirmConfig {
    //queue
    public static final String CONFIRM_QUEUE = "CONFIRM_QUEUE";
    //Switch
    public static final String CONFIRM_EXCHANGE = "CONFIRM_EXCHANGE";
    //routingKey
    public static final String CONFIRM_ROUNTING_KEY = "CONFIRM_ROUNTING_KEY";
    //Backup switch
    public static final String BACKUP_EXCHANGE = "BACKUP_EXCHANGE";
    //Backup queue
    public static final String BACKUP_QUEUE = "BACKUP_QUEUE";
    //Alarm queue
    public static final String WARNING_QUEUE = "WARNING_QUEUE";


    //Declaration switch
    //Because the previous switch is used here, the original switch needs to be deleted to take effect
    @Bean
    public DirectExchange confirmEchange() {
        return (DirectExchange) ExchangeBuilder.directExchange(CONFIRM_EXCHANGE).durable(true).withArgument("alternate-exchange", BACKUP_EXCHANGE).build();
    }

    //Declare backup switch
    @Bean
    public FanoutExchange backupEchange() {
        return new FanoutExchange(BACKUP_EXCHANGE);
    }


    //Declaration queue
    @Bean
    public Queue confirmQueue() {
        //Create queue
        return new Queue(CONFIRM_QUEUE);
    }

    //Declare backup queue
    @Bean
    public Queue backupQueue() {
        //Create queue
        return new Queue(BACKUP_QUEUE);
    }

    //Declare alarm queue
    @Bean
    public Queue warningQueue() {
        //Create queue
        return new Queue(WARNING_QUEUE);
    }


    //Bind queue
    @Bean
    public Binding confirmBindingQueue(@Qualifier("confirmQueue") Queue confirmQueue, @Qualifier("confirmEchange") DirectExchange confirmEchange) {
        return BindingBuilder.bind(confirmQueue).to(confirmEchange).with(CONFIRM_ROUNTING_KEY);
    }

    //Bind backup queue
    @Bean
    public Binding backupBindingQueue(@Qualifier("backupQueue") Queue backupQueue, @Qualifier("backupEchange") FanoutExchange backupEchange) {
        return BindingBuilder.bind(backupQueue).to(backupEchange);
    }

    //Bind alarm queue
    @Bean
    public Binding warningBindingQueue(@Qualifier("warningQueue") Queue warningQueue, @Qualifier("backupEchange") FanoutExchange backupEchange) {
        return BindingBuilder.bind(warningQueue).to(backupEchange);
    }

}

Consumer alert

package com.rabbitmq11;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * Queue ttl consumers
 *
 * @author Naive heat
 * @create 2022-02-10 16:00
 * @desc
 **/
@Slf4j
@Component
public class WarningConsume {
    //receive messages
    @RabbitListener(queues = ConfirmConfig.WARNING_QUEUE)
    public void receiveDelay(Message msg) {

        String message = new String(msg.getBody());
        log.info("Alarm found non routable message:" + message);
    }
}

Backup consumer

package com.rabbitmq11;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * Queue ttl consumers
 *
 * @author Naive heat
 * @create 2022-02-10 16:00
 * @desc
 **/
@Slf4j
@Component
public class BackupConsume {
    //receive messages
    @RabbitListener(queues = ConfirmConfig.BACKUP_QUEUE)
    public void receiveDelay(Message msg) {

        String message = new String(msg.getBody());
        log.info("Backup switch message:" + message);
    }
}

Test 1 - normal access: http://localhost:8090/confirm/sendMsg/100

Test 2 - access the wrong route: http://localhost:8090/confirm/sendMsgToBadExchange/100

Test 3 - access the wrong routingkey: http://localhost:8090/confirm/sendMsgToBadRounting/100

16, Introduction to RabbitMq's interface Features attribute

  1. d: d is the abbreviation of durable, which means that the messages in this queue support persistence.
  2. ad: ad is an abbreviation for autoDelete. The last consumer representing the current queue is automatically deleted when unsubscribing. Note: at this time, the queue will be deleted regardless of whether there are messages in the queue.
  3. excl: it is the abbreviation of exclusive. It means this is an exclusive queue. If a queue is declared as an exclusive queue, it is only visible to the connection that first declared it and is automatically deleted when the connection is disconnected. Three points need to be noted here: first, the exclusive queue is visible based on the connection. Different channels of the same connection can access the exclusive queue created by the same connection at the same time. Second, for the first time, if a connection has declared an exclusive queue, other connections are not allowed to establish an exclusive queue with the same name, which is different from ordinary queues. Third, even if the queue is persistent, once the connection is closed or the client exits, the exclusive queue will be deleted automatically. This queue is applicable to the application scenario where only one client sends read messages.
  4. Args: short for arguments. The arguments parameter is configured on behalf of the queue.
  5. TTL: it is the abbreviation of x-message-ttl. Set the life cycle of all messages in the queue (uniformly set the life cycle for all messages in the whole queue), or specify the remaining life time for a message separately when publishing a message, in milliseconds.
  6. Exp: Auto Expire is the abbreviation of x-expires configuration. When the queue is not accessed at the specified time (consume, basicGet, queueDeclare...), it will be deleted. Features=Exp. Note that this is to delete the queue, not the messages in the queue.
  7. Lim: indicates that the queue is configured with x-max-length. Limit the maximum length of messages in the queue. If it exceeds the specified length, the earliest messages will be deleted.
  8. Lim B: indicates that the queue is configured with x-max-length-bytes. Limit the maximum space occupied by the queue, which is generally limited by the size of memory and disk.
  9. DLX: indicates that the queue is configured with x-dead-letter-exchange. When the queue message length is greater than the maximum length or expired, push the messages deleted from the queue to the specified switch instead of discarding them.
  10. DLK: abbreviation of x-dead-letter-routing-key, which pushes the deleted message to the queue of the specified routing key of the specified switch.
  11. Pri: abbreviation of x-max-priority, priority queue. It indicates that the queue supports priority. First define the maximum priority value (the maximum value is generally not too large), specify the priority of the message when publishing the message, and the messages with higher priority (higher value) are consumed first.
  12. Ovfl: abbreviation for x-overflow. How to handle messages in the queue when they overflow. Either discard the message at the head of the queue, or reject all messages sent by subsequent producers. There are two configuration items: drop head, which represents the message discarding the queue head. The default behavior is; Reject publish sets the behavior of the queue after message overflow in the queue: "reject" (all messages).
  13. Ha all: mirror queue. All indicates that all nodes on the cluster are mirrored, and the HA params parameter is ignored.

Topics: Java RabbitMQ