RabbitMQ explains five kinds of queues - SpiritMark

Posted by irwa82 on Mon, 28 Oct 2019 07:51:45 +0100

Last time I took you to see the basic concept of RabbitMQ. Today we will explain the five kinds of queues of RabbitMQ in detail, which is also a note. Later I forget it. You can review it. If you think my brother's article is helpful to you, pay attention to my little brother, and your support is my greatest encouragement.

@[toc]

1. Simple queue

The producer sends the message to the "hello" queue. Consumers receive messages from this queue.

① pom file

rabbitmq dependency package must be imported

 <dependency>
      <groupId>com.rabbitmq</groupId>
       <artifactId>amqp-client</artifactId>
       <version>3.4.1</version>
 </dependency>

②. Tools

package com.spiritmark.rabbitmq.util;

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

import java.io.IOException;

public class RabbitUtil {

    public static Connection getConnection(String virtual,String username,String password,int port) throws IOException {
            ConnectionFactory factory = new ConnectionFactory();
            // Set virtual host address
            factory.setVirtualHost(virtual);
            //Set login user
            factory.setUsername(username);
            //Set password
            factory.setPassword(password);
            //Set port number
            factory.setPort(port);
            return  factory.newConnection();
    }

}

③ Producer

package com.spiritmark.simple;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.ys.utils.ConnectionUtil;

/**
 * Create by YSOcean
 */
public class Producer {
    private final static String QUEUE_NAME = "hello";

    public static void main(String[] args) throws Exception{
        //1. Get the connection
        Connection connection = ConnectionUtil.getConnection("192.168.146.251",5672,"/","guest","guest");
        //2. Declaration channel
        Channel channel = connection.createChannel();
        //3. Declaration (creation) queue
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        //4. Define message content
        String message = "hello rabbitmq ";
        //5. Release information
        channel.basicPublish("",QUEUE_NAME,null,message.getBytes());
        System.out.println("[x] Sent'"+message+"'");
        //6. Close the channel
        channel.close();
        //7. Close the connection
        connection.close();
    }
}

④. Consumer

package com.spiritmark.simple;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import com.ys.utils.ConnectionUtil;


/**
 * Create by YSOcean
 */
public class Consumer {

    private final static String QUEUE_NAME = "hello";

    public static void main(String[] args) throws Exception{
        //1. Get the connection
        Connection connection = ConnectionUtil.getConnection("192.168.146.251",5672,"/","guest","guest");
        //2. Declaration channel
        Channel channel = connection.createChannel();
        //3. Declaration queue
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        //4. Define the consumers in the queue
        QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
        //5. Listening queue
        /*
            true:Indicates automatic confirmation. As long as the message is obtained from the queue, the message will be considered to have been successfully consumed no matter whether the consumer has successfully consumed the message or not.
            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 give it again
                   Send a message until the consumer gives feedback.
         */

        channel.basicConsume(QUEUE_NAME,true,queueingConsumer);
        //6. Get information
        while (true){
            QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
            String message = new String(delivery.getBody());
            System.out.println(" [x] Received '" + message + "'");
        }
    }

}

Note that there are two modes for consumers to confirm messages automatically and manually.

2. work mode

One producer corresponds to more than one consumer, but only one consumer can get the message!

Competitive consumer model.

①. Producers

package com.spiritmark.workqueue;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.ys.utils.ConnectionUtil;

/**
 * Create by YSOcean
 */
public class Producer {
    private final static String QUEUE_NAME = "work_queue";

    public static void main(String[] args) throws Exception{
        //1. Get the connection
        Connection connection = ConnectionUtil.getConnection("192.168.146.251",5672,"/","guest","guest");
        //2. Declaration channel
        Channel channel = connection.createChannel();
        //3. Declaration (creation) queue
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        //4. Define message content (publish multiple messages)
        for(int i = 0 ; i < 10 ; i++){
            String message = "hello rabbitmq "+i;
            //5. Release information
            channel.basicPublish("",QUEUE_NAME,null,message.getBytes());
            System.out.println("[x] Sent'"+message+"'");
            //Simulate the delay of sending messages, so as to demonstrate multiple consumers' competitive acceptance of messages
            Thread.sleep(i*10);
        }
        //6. Close the channel
        channel.close();
        //7. Close the connection
        connection.close();
    }
}

②. Consumers

Create two consumers here

Consumer 1: sleep 10 ms after receiving a message

package com.spiritmark.workqueue;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import com.ys.utils.ConnectionUtil;


/**
 * Create by YSOcean
 */
public class Consumer1 {

    private final static String QUEUE_NAME = "work_queue";

    public static void main(String[] args) throws Exception{
        //1. Get the connection
        Connection connection = ConnectionUtil.getConnection("192.168.146.251",5672,"/","guest","guest");
        //2. Declaration channel
        Channel channel = connection.createChannel();
        //3. Declaration queue
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        //At the same time, the server will send only one message to the consumer
        //channel.basicQos(1);

        //4. Define the consumers in the queue
        QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
        //5. Listen to the queue and return to completion status manually
        channel.basicConsume(QUEUE_NAME,false,queueingConsumer);
        //6. Get information
        while (true){
            QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
            String message = new String(delivery.getBody());
            System.out.println(" [x] Received '" + message + "'");
            //Consumer 1 sleeps for 10 ms after receiving a message
            Thread.sleep(10);
            //Return to confirmation status
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
        }
    }

}

Consumer 2: sleep 1000 ms after receiving a message

package com.spiritmark.workqueue;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import com.ys.utils.ConnectionUtil;


/**
 * Create by YSOcean
 */
public class Consumer2 {

    private final static String QUEUE_NAME = "work_queue";

    public static void main(String[] args) throws Exception{
        //1. Get the connection
        Connection connection = ConnectionUtil.getConnection("192.168.146.251",5672,"/","guest","guest");
        //2. Declaration channel
        Channel channel = connection.createChannel();
        //3. Declaration queue
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        //At the same time, the server will send only one message to the consumer
        //channel.basicQos(1);

        //4. Define the consumers in the queue
        QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
        //5. Listen to the queue and return to completion status manually
        channel.basicConsume(QUEUE_NAME,false,queueingConsumer);
        //6. Get information
        while (true){
            QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
            String message = new String(delivery.getBody());
            System.out.println(" [x] Received '" + message + "'");
            //Consumer 2 sleeps for 1000 milliseconds after receiving a message
            Thread.sleep(1000);
            //Return to confirmation status
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
        }
    }

}

③ test results

First, the producer prints 0-9 messages at a time. Next let's look at consumer 1: the result is to print even messages

Consumer 2: the result is to print an odd number of messages

④ analysis results

The message content obtained by consumers 1 and 2 is different, that is to say, the same message can only be obtained by one consumer.

Consumer 1 and consumer 2 get odd messages and even messages respectively, and the number of messages obtained is the same.

As we said earlier, this mode is a competitive consumer mode. A queue is monitored by multiple consumers. Here, two consumers, consumer 1 and consumer 2, sleep for 10 and 1000 milliseconds respectively after getting messages. That is to say, the efficiency of the two consumers to get messages is different, but the result is that the number of messages they get is the same, which is basically the same. It doesn't form a competitive relationship, so what can we do to make consumers with high efficiency get more information, that is, consumers 1 get more information?

PS: in addition to a consumer, the number of messages obtained is the same. Consumer 1 gets 0, 3, 6, 9, consumer 2 gets 1, 4, 7, consumer 3 gets 2, 5, 8.

⑤. There are many talents

channel.basicQos(1);

Add the above code to indicate that the server will send only one message to the consumer at the same time. Consumer 1 and consumer 2 get the message results as follows: ⑥ application scenario

Efficient consumers consume a lot of information. It can be used for load balancing.

3. Publish / subscribe mode

A consumer first sends a message to a switch, which binds to multiple queues, and then is received and consumed by consumers listening to the queues.

Note: X refers to the switch. In RabbitMQ, there are four types of switches: direct, fanout, topic, and headers. The switch here is fanout. We will introduce these switches in detail.

①. Producers

package com.spiritmark.workqueue;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.ys.utils.ConnectionUtil;

/**
 * Create by YSOcean
 */
public class Producer {
    private final static String QUEUE_NAME = "work_queue";

    public static void main(String[] args) throws Exception{
         //1. Get the connection
        Connection connection = ConnectionUtil.getConnection("192.168.146.251", 5672, "/", "guest", "guest");
        //2. Declaration channel
        Channel channel = connection.createChannel();
        //3. Declaration exchange
        channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
        //4. Create message
        String message = "hello rabbitmq";
        //5. Release information
        channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes());
        System.out.println("[x] Sent'" + message + "'");
        //6. Close the channel
        channel.close();
        //7. Close the connection
        connection.close();
        }
}

②. Consumers

Create two consumers here

Consumer 1: sleep 10 ms after receiving a message

package com.spiritmark.workqueue;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import com.ys.utils.ConnectionUtil;


/**
 * Create by YSOcean
 */
public class Consumer1 {

    private final static String QUEUE_NAME = "work_queue";

    public static void main(String[] args) throws Exception{
       //1. Get the connection
        Connection connection = ConnectionUtil.getConnection("192.168.146.251",5672,"/","guest","guest");
        //2. Declaration channel
        Channel channel = connection.createChannel();
        //3. Declaration queue
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        //4. Bind queue to switch
        channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"");
        //At the same time, the server will send only one message to the consumer
        channel.basicQos(1);
        //5. Define the consumers in the queue
        QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
        //6. Monitor the queue and return to completion status manually
        channel.basicConsume(QUEUE_NAME,false,queueingConsumer);
        //6. Get information
        while (true){
            QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
            String message = new String(delivery.getBody());
            System.out.println(" Consumer 1:" + message + "'");
            //Consumer 1 sleeps for 10 ms after receiving a message
            Thread.sleep(10);
            //Return to confirmation status
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
        }
    }

}

Consumer 2: sleep 1000 ms after receiving a message

package com.spiritmark.workqueue;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import com.ys.utils.ConnectionUtil;


/**
 * Create by YSOcean
 */
public class Consumer2 {

    private final static String QUEUE_NAME = "work_queue";

    public static void main(String[] args) throws Exception{
      //1. Get the connection
        Connection connection = ConnectionUtil.getConnection("192.168.146.251",5672,"/","guest","guest");
        //2. Declaration channel
        Channel channel = connection.createChannel();
        //3. Declaration queue
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        //4. Bind queue to switch
        channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"");
        //At the same time, the server will send only one message to the consumer
        channel.basicQos(1);
        //5. Define the consumers in the queue
        QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
        //6. Monitor the queue and return to completion status manually
        channel.basicConsume(QUEUE_NAME,false,queueingConsumer);
        //6. Get information
        while (true){
            QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
            String message = new String(delivery.getBody());
            System.out.println(" Consumer 2:" + message + "'");
            //Consumer 2 sleeps for 10 ms after receiving a message
            Thread.sleep(1000);
            //Return to confirmation status
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
        }
    }

}

Note: the queue names monitored by consumer 1 and consumer 2 are different. We can see from the foreground management system: ③ test results

Both consumer 1 and consumer 2 consumed the message.

ps: This is because both consumer 1 and consumer 2 listen to queues bound by the same switch. If a message is sent to a switch that does not have a queue binding, the message is lost because the switch does not have the ability to store the message and the message can only be stored in the queue.

④ application scenario

For example, when an administrator uploads a new picture of a commodity in a mall system, the foreground system must update the picture, and the log system must record the corresponding log. Then two queues can be bound to the picture upload switch, one for the foreground system to update the picture, and the other for the log system to record the log.

4. Routing mode

①. Producers

package com.spiritmark.routing;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.ys.utils.ConnectionUtil;

/**
 * Create by YSOcean
 */
public class Producer {
    private final static String EXCHANGE_NAME = "direct_exchange";

    public static void main(String[] args) throws Exception {
        //1. Get the connection
        Connection connection = ConnectionUtil.getConnection("192.168.146.251", 5672, "/", "guest", "guest");
        //2. Declaration channel
        Channel channel = connection.createChannel();
        //3. Declare the exchanger as direct.
        channel.exchangeDeclare(EXCHANGE_NAME, "direct");
        //4. Create message
        String message = "hello rabbitmq";
        //5. Release information
        channel.basicPublish(EXCHANGE_NAME, "update", null, message.getBytes());
        System.out.println("Sent by producer" + message + "'");
        //6. Close the channel
        channel.close();
        //7. Close the connection
        connection.close();
    }
}

  ②. Consumers Consumer 1:

package com.spiritmark.routing;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import com.ys.utils.ConnectionUtil;


/**
 * Create by YSOcean
 */
public class Consumer1 {

    private final static String QUEUE_NAME = "direct_queue_1";

    private final static String EXCHANGE_NAME = "direct_exchange";

    public static void main(String[] args) throws Exception{
        //1. Get the connection
        Connection connection = ConnectionUtil.getConnection("192.168.146.251",5672,"/","guest","guest");
        //2. Declaration channel
        Channel channel = connection.createChannel();
        //3. Declaration queue
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        //4. Bind the queue to the switch, and specify the route key as update.
        channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"update");
        channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"delete");
        channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"add");
        //At the same time, the server will send only one message to the consumer
        channel.basicQos(1);
        //5. Define the consumers in the queue
        QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
        //6. Monitor the queue and return to completion status manually
        channel.basicConsume(QUEUE_NAME,false,queueingConsumer);
        //6. Get information
        while (true){
            QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
            String message = new String(delivery.getBody());
            System.out.println(" Consumer 1:" + message + "'");
            //Consumer 1 sleeps for 10 ms after receiving a message
            Thread.sleep(10);
            //Return to confirmation status
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
        }
    }

}

Consumer 2:

package com.spiritmark.routing;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import com.ys.utils.ConnectionUtil;


/**
 * Create by YSOcean
 */
public class Consumer2 {

    private final static String QUEUE_NAME = "direct_queue_2";

    private final static String EXCHANGE_NAME = "direct_exchange";

    public static void main(String[] args) throws Exception{
        //1. Get the connection
        Connection connection = ConnectionUtil.getConnection("192.168.146.251",5672,"/","guest","guest");
        //2. Declaration channel
        Channel channel = connection.createChannel();
        //3. Declaration queue
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        //4. Bind the queue to the switch, and specify the route key as select.
        channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"select");
        //At the same time, the server will send only one message to the consumer
        channel.basicQos(1);
        //5. Define the consumers in the queue
        QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
        //6. Monitor the queue and return to completion status manually
        channel.basicConsume(QUEUE_NAME,false,queueingConsumer);
        //6. Get information
        while (true){
            QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
            String message = new String(delivery.getBody());
            System.out.println(" Consumer 1:" + message + "'");
            //Consumer 2 sleeps for 10 ms after receiving a message
            Thread.sleep(1000);
            //Return to confirmation status
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
        }
    }

}

③ test results    Let's first look at the code. The producer publishes the message. The specified route key is update. When consumer 1 binds queues and switches, the key is update/delete/add; when consumer 2 binds queues and switches, the key is select.

So we can guess that only consumer 1 can receive and consume the messages sent by producers, while consumer 2 cannot.

④ application scenario

Taking advantage of the characteristics that consumers can selectively receive messages, for example, the background management system of our mall system needs to update the interface display of the foreground system to modify, delete and add goods, while the query operation does not need to, so it is better to separate the two queues to receive messages.

5. Theme mode

①. Producers

package com.spiritmark.topic;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.ys.utils.ConnectionUtil;

/**
 * Create by YSOcean
 */
public class Producer {
    private final static String EXCHANGE_NAME = "topic_exchange";

    public static void main(String[] args) throws Exception {
        //1. Get the connection
        Connection connection = ConnectionUtil.getConnection("192.168.146.251", 5672, "/", "guest", "guest");
        //2. Declaration channel
        Channel channel = connection.createChannel();
        //3. Declare the exchanger as direct.
        channel.exchangeDeclare(EXCHANGE_NAME, "topic");
        //4. Create message
        String message = "hello rabbitmq111";
        //5. Release information
        channel.basicPublish(EXCHANGE_NAME, "update.Name", null, message.getBytes());
        System.out.println("Sent by producer" + message + "'");
        //6. Close the channel
        channel.close();
        //7. Close the connection
        connection.close();
    }
}

②. Consumers

Consumer 1:

package com.spiritmark.topic;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import com.ys.utils.ConnectionUtil;


/**
 * Create by YSOcean
 */
public class Consumer1 {

    private final static String QUEUE_NAME = "topic_queue_1";

    private final static String EXCHANGE_NAME = "topic_exchange";

    public static void main(String[] args) throws Exception{
        //1. Get the connection
        Connection connection = ConnectionUtil.getConnection("192.168.146.251",5672,"/","guest","guest");
        //2. Declaration channel
        Channel channel = connection.createChannel();
        //3. Declaration queue
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        //4. Bind the queue to the switch, and specify the route key as update.#
        channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"update.#");
        //At the same time, the server will send only one message to the consumer
        channel.basicQos(1);
        //5. Define the consumers in the queue
        QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
        //6. Monitor the queue and return to completion status manually
        channel.basicConsume(QUEUE_NAME,false,queueingConsumer);
        //6. Get information
        while (true){
            QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
            String message = new String(delivery.getBody());
            System.out.println(" Consumer 1:" + message + "'");
            //Consumer 1 sleeps for 10 ms after receiving a message
            Thread.sleep(10);
            //Return to confirmation status
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
        }
    }

}

Consumption 2:

package com.spiritmark.topic;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import com.ys.utils.ConnectionUtil;


/**
 * Create by YSOcean
 */
public class Consumer2 {

    private final static String QUEUE_NAME = "topic_queue_2";

    private final static String EXCHANGE_NAME = "topic_exchange";

    public static void main(String[] args) throws Exception{
        //1. Get the connection
        Connection connection = ConnectionUtil.getConnection("192.168.146.251",5672,"/","guest","guest");
        //2. Declaration channel
        Channel channel = connection.createChannel();
        //3. Declaration queue
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        //4. Bind the queue to the switch, and specify the route key as select.#
        channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"select.#");
        //At the same time, the server will send only one message to the consumer
        channel.basicQos(1);
        //5. Define the consumers in the queue
        QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
        //6. Monitor the queue and return to completion status manually
        channel.basicConsume(QUEUE_NAME,false,queueingConsumer);
        //6. Get information
        while (true){
            QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
            String message = new String(delivery.getBody());
            System.out.println(" Consumer 1:" + message + "'");
            //Consumer 2 sleeps for 10 ms after receiving a message
            Thread.sleep(1000);
            //Return to confirmation status
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
        }
    }

}

③ analysis results

The route key of the producer sending message binding is update.Name; the route key of the consumer 1 listening queue and the switch binding is update. ා; the route key of the consumer 2 listening queue and the switch binding is select. ා.

Obviously, consumer 1 will receive a message, while consumer 2 will not.

6. Four types of exchanger

The first five queue modes are introduced, but there are only three. The first is a simple queue, the second is a working mode, and the remaining three are all bound to the switch. In this section, we will introduce the switch in detail.

There are four types of switches: direct, fanout, topic and headers.

The first three correspond to the routing mode, publish / subscribe mode and wildcard mode respectively. The headers switch allows to match the header of AMQP messages instead of the routing key. In addition, the header switch and the direct switch are exactly the same, but the performance is much worse, so the switch is not used basically, and will not be described in detail here.

  ①,direct

If the routing keys match exactly, the message will be put into the corresponding queue.

②,fanout

When a message is sent to a fanout switch, it places the message on all queues attached to the switch.

③,topic

Set the fuzzy binding method. The "*" operator regards "." as a separator to match a single character; the "ා" operator does not have the concept of blocking. It regards any "." as the matching part of the keyword, which can match multiple characters.

7, summary

As for the five queues of RabbitMQ, actually, the most commonly used is the last theme mode, which makes the operation more comfortable through fuzzy matching. Let's summarize the work mode of queues (the last three queues) with switch participation as follows:  

Topics: Programming RabbitMQ Java