RabbitMQ learning experience

Keywords: RabbitMQ Java Session Attribute

The following is an introduction from MQ to RabbitMQ, and a demo of the six working modes of RabbitMQ

MQ:
MQ is called Message Queue. It is translated as Message Queue. MQ is a communication method between applications. Applications communicate by writing and retrieving queued application specific data, without having to link them with a dedicated connection. Message passing refers to the communication between programs by sending data in messages, rather than directly calling each other. Direct calling is usually used for technologies such as remote procedure call. Queuing refers to the application communicating through queues. The use of queues removes the requirement that both receiving and sending applications execute at the same time.

The above introduction is Baidu professional introduction, too "professional", simple understanding is a message queue, used for mutual communication between programs

RabbitMQ:

RabbitMQ is called Advanced Message Queue, that is, Advanced Message Queue protocol. It is developed by Erlang language and implemented based on AMQP protocol (there are many products of MQ, such as ActiveMQ, kafka, ZeroMQ, etc. it is worth mentioning that Redis is also a member of MQ).
The operating systems supported by RabbitMQ, such as Linux, Windows, MaxOX, etc. (currently supported by the mainstream operating systems).
Support multiple development languages, such as Java, Python, Ruby, etc.

AMQP protocol is mentioned above, so what is AMQP protocol?
AMQP, Advanced Message Queuing Protocol, is an application layer standard Advanced Message Queuing Protocol that provides unified message service. It is an open standard of application layer protocol and is designed for message oriented middleware. Based on this protocol, the client and message middleware can deliver messages, which is not limited by different products and different development languages. The implementation in Erlang includes RabbitMQ and so on.

"Professional" Baidu will never let you down. Conclusion: AMQP is a set of open message queuing protocol, which was first proposed in 2003. It aims to define the standard format of message communication data from the protocol layer, in order to solve the problem of protocol inconsistency in MQ market. RabbitMQ is an MQ service developed according to AMQP standard protocol.

How RabbitMQ works

The following figure shows the basic structure of RabbitMQ:

The components are described as follows:

  • Broker: Message Queuing service process, which consists of two parts: Exchange and Queue.
  • Exchange: Message Queuing switch, which forwards the message route to a certain queue according to certain rules to filter the messages.
  • Queue: message queue, which stores messages. Messages arrive at the queue and are forwarded to the specified consumer.
  • Producer: the message producer, that is, the producer client, which sends the message to MQ.
  • Consumer: message consumer, that is, consumer client, receives messages forwarded by MQ.
Message publishing and receiving process:

Send message:

  1. The producer and Broker establish a TCP connection.
  2. Producers and brokers establish channels.
  3. The producer sends the channel message to the Broker, and Exchange forwards the message.
  4. Exchange forwards messages to the specified Queue

Receive message:

  1. Consumer and Broker establish TCP connection
  2. Channel between consumer and Broker
  3. Consumer listens to the specified Queue
  4. When a message arrives at the Queue, the Broker pushes the message to the consumer by default.
  5. Consumer received message.

Working mode of RabbitMQ

First, use the official java client of rabbitmq to write a normal rabbitmq working mode (a production, a consumption)
  1. Create maven project
    Create producer project and consumer project, respectively, and add the dependency of RabbitMQ java client.
    Test rabbitmq producer: producer Engineering
    Test rabbitmq consumer: consumer Engineering
<dependency>
	<groupId>com.rabbitmq</groupId>
	<artifactId>amqp‐client</artifactId>
	<version>4.0.3</version> 
	<!--This version and spring boot 1.5.9Version matching-->
</dependency>

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring‐boot‐starter‐logging</artifactId>
</dependency>
  1. Producer code
public class Producer01 {
    //Queue name
    private static final String QUEUE = "helloworld";

    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = null;
        Channel channel = null;
        try {
            ConnectionFactory factory = new ConnectionFactory();
            factory.setHost("localhost");
            factory.setPort(5672);
            factory.setUsername("guest");
            factory.setPassword("guest");
            factory.setVirtualHost("/");//rabbitmq default virtual machine name is "/", virtual machine is equivalent to an independent mq service
            //implement
//Create a TCP connection to the RabbitMQ service
                    connection = factory.newConnection();
//Create channels with Exchange. Each connection can create multiple channels. Each channel represents a session task
            channel = connection.createChannel();
            /**
             * Declare the queue. If there is no such queue in Rabbit, it will be created automatically
             * param1:Queue name
             * param2:Persistence or not
             * param3:Is this connection exclusive to the queue
             * param4:Automatically delete the queue when it is no longer in use
             * param5:Queue parameters
             */
            channel.queueDeclare(QUEUE, true, false, false, null);
            String message = "helloworld Xiao Ming" + System.currentTimeMillis();
            /**
             * Message publishing method
             * param1: Exchange If not specified, use Default Exchange
             * param2:routingKey,The routing Key of the message, which is used by Exchange to forward the message to the specified message queue
             * param3:Properties contained in message
             * param4: Message body
             */
            /**
             * There is no switch specified here, the message will be sent to the default switch, and each queue will also be bound to the default switch, but it cannot be displayed
             Show bind or unbind
             * Default switch, routingKey is equal to queue name
             */
            channel.basicPublish("", QUEUE, null, message.getBytes());
            System.out.println("Send Message is:'" + message + "'");
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            if (channel != null) {
                channel.close();
            }
            if (connection != null) {
                connection.close();
            }
        }
    }
}
  1. Consumer code
public class Consumer01 {
    private static final String QUEUE = "helloworld";
    
    public static void main(String[] args) throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        //Set the ip and port of the server where MabbitMQ is located
        factory.setHost("127.0.0.1");
        factory.setPort(5672);
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();
        //Declaration queue
        channel.queueDeclare(QUEUE, true, false, false, null);
        //Define consumption method
        DefaultConsumer consumer = new DefaultConsumer(channel) {
            /**
             * Consumer receives message call this method
             * 
             * @param consumerTag The label of the consumer is specified in channel.basicConsume()
             * @param envelope The content of the message package, from which the message id, message routingkey, switch, message and retransmission flag can be obtained (whether to resend after receiving the message failure)
             * @param properties
             * @param body
             * @throws IOException
             */
            @Override
            public void handleDelivery(String consumerTag,
                                       Envelope envelope,
                                       AMQP.BasicProperties properties,
                                       byte[] body)
                    throws IOException {
                //Switch
                String exchange = envelope.getExchange();
                //Routing key
                String routingKey = envelope.getRoutingKey();
                //Message id
                long deliveryTag = envelope.getDeliveryTag();
                //Message content
                String msg = new String(body,"utf‐8");
                System.out.println("receive message.." + msg);
            }
        };
    /**
     * Listening queue String queue, boolean autoAck,Consumer callback
     * 
     * Parameter details
     *  1,Queue name
     *  2,Whether to reply automatically. If it is set to true, it means that the message has been automatically replied to mq when it is received. If it is set to false, you need to reply manually
     *  3,The method of consuming messages is called by consumers after receiving messages.
     */
        channel.basicConsume(QUEUE, true, consumer);
    }
}
1. Work queues

Compared with one production one consumption mode, work queues mode has one more consumer end, and two consumers consume messages in the same queue together (just copy the consumer end code).
Application scenario: using work queues can improve the speed of task processing when tasks are too heavy or too many.
Characteristic:

  1. A message can only be received by one consumer.
  2. rabbit uses polling to send messages to consumers on average.
  3. Consumers will not receive the next message until they have processed one.
2. Publish/Subscribe

In Publish/Subscribe mode, each consumer listens to its own queue. The producer sends the message to the broker, and the switch forwards the message to each queue bound to the switch, and each queue bound to the switch receives the message.

  • Producer test code:
    Declare the exchange fanout information switch.
    Two queues are declared and bound to this switch. routingkey does not need to be specified when binding
    You do not need to specify routingkey when sending messages
package com.rabbitmq.test;

import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class Producer02_publish {
    //Queue name
    private static final String QUEUE_INFORM_EMAIL = "queue_inform_email";
    private static final String QUEUE_INFORM_SMS = "queue_inform_sms";
    private static final String EXCHANGE_FANOUT_INFORM = "exchange_fanout_inform";

    public static void main(String[] args) {
        Connection connection = null;
        Channel channel = null;
        try {
            //Create a connection to MQ
            ConnectionFactory factory = new ConnectionFactory();
            factory.setHost("127.0.0.1");
            factory.setPort(5672);
            factory.setUsername("guest");
            factory.setPassword("guest");
            factory.setVirtualHost("/"); //rabbitmq default virtual machine name is "/", virtual machine is equivalent to an independent mq server
            //Create a connection
            connection = factory.newConnection();
            //Create channels with the switch, each representing a session
            channel = connection.createChannel();
            //Declare switch string exchange, builtinexchangetype
            /**
             * Parameter details
             *  1,Switch name
             *  2,Switch type, fanout, topic, direct, headers
             */
            channel.exchangeDeclare(EXCHANGE_FANOUT_INFORM, BuiltinExchangeType.FANOUT);
            //Declaration queue
            //(String queue,boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object > arguments)
            /**
             * Parameter details:
             *  1,Queue name
             *  2,Persistence or not
             *  3,Is this queue exclusive
             *  4,Queue does not need to be deleted automatically
             *  5,parameter
             */
            channel.queueDeclare(QUEUE_INFORM_EMAIL, true, false, false, null);
            channel.queueDeclare(QUEUE_INFORM_SMS, true, false, false, null);
            //Switch and queue binding String queue, String exchange, String routingKey
            /**
             * Parameter details
             *  1,Queue name
             *  2,Switch name
             *  3,Routing key
             */
            channel.queueBind(QUEUE_INFORM_EMAIL, EXCHANGE_FANOUT_INFORM, "");
            channel.queueBind(QUEUE_INFORM_SMS, EXCHANGE_FANOUT_INFORM, "");
            //send message
            for (int i = 0; i < 10; i++) {
                String message = "inform to user" + i;
                //Send message String exchange, String routingKey, BasicProperties props,byte[] body to switch
                /**
                 * Parameter details
                 *  1,Switch name, do not instruct to use default switch name Default Exchange
                 *  2,routingKey(Route key). Forward the message to a specific queue according to the key name. Fill in the queue name here to indicate that the message will be sent to this queue
                 *  3,Message attribute
                 *  4,Message content
                 */
                channel.basicPublish(EXCHANGE_FANOUT_INFORM, "", null, message.getBytes());
                System.out.println("Send Message is:'" + message + "'");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        } finally {
            if (channel != null) {
                try {
                    channel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (TimeoutException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
  • Consumer test code
package com.rabbitmq.test;

import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @author Administrator
 * @version 1.0
 * @create 2018‐06‐14 10:32
 **/
public class Consumer02_subscribe_email {
    //Queue name
    private static final String QUEUE_INFORM_EMAIL = "inform_queue_email";
    private static final String EXCHANGE_FANOUT_INFORM = "inform_exchange_fanout";

    public static void main(String[] args) throws IOException, TimeoutException {
        //Create a connection to MQ
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("127.0.0.1");
        factory.setPort(5672);
        factory.setUsername("guest");
        factory.setPassword("guest");
        factory.setVirtualHost("/");//rabbitmq default virtual machine name is "/", virtual machine is equivalent to an independent mq server
        //Create a connection
        Connection connection = factory.newConnection();
        //Create channels with the switch, each representing a session
        Channel channel = connection.createChannel();
        //Declare switch string exchange, builtinexchangetype
        /**
         * Parameter details
         *  1,Switch name
         *  2,Switch type, fanout, topic, direct, headers
         */
        channel.exchangeDeclare(EXCHANGE_FANOUT_INFORM, BuiltinExchangeType.FANOUT);
        //Declaration queue
        // channel.queueDeclare(String queue, boolean durable, boolean exclusive, booleanautoDelete, Map<String, Object> arguments)
        /**
         * Parameter details:
         *  1,Queue name
         *  2,Persistence or not
         *  3,Is this queue exclusive
         *  4,Queue does not need to be deleted automatically
         *  5,parameter
         */
        channel.queueDeclare(QUEUE_INFORM_EMAIL, true, false, false, null);
        //Switch and queue binding String queue, String exchange, String routingKey
        /**
         * Parameter details
         *  1,Queue name
         *  2,Switch name
         *  3,Routing key
         */
        channel.queueBind(QUEUE_INFORM_EMAIL, EXCHANGE_FANOUT_INFORM, "");
        //Define consumption method
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope,
                                       AMQP.BasicProperties properties, byte[] body) throws IOException {
                long deliveryTag = envelope.getDeliveryTag();
                String exchange = envelope.getExchange();
                //Message content
                String message = new String(body, "utf‐8");
                System.out.println(message);
            }
        };
        /**
         * Listening queue String queue, boolean autoAck,Consumer callback
         * Parameter details
         *  1,Queue name
         *  2,Whether to reply automatically. If it is set to true, it means that the message has been automatically replied to mq when it is received. If it is set to false, you need to reply manually
         *  3,The method of consuming messages is called by consumers after receiving messages.
         */
        channel.basicConsume(QUEUE_INFORM_EMAIL, true, defaultConsumer);
    }
}
3. Routing

In Routing mode, each consumer listens to its own queue and sets routingkey. The producer sends the message to the switch, which forwards the message to the specified queue according to routingkey.

  • Routing production side test code
    Declare the exchange? Routing? Information switch.
    Declare two queues and bind to this switch. When binding, you need to specify routingkey
    routingkey needs to be specified when sending messages
package com.rabbitmq.test;

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

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

public class Producer03_routing {
    //Queue name
    private static final String QUEUE_INFORM_EMAIL = "queue_inform_email";
    private static final String QUEUE_INFORM_SMS = "queue_inform_sms";
    private static final String EXCHANGE_ROUTING_INFORM = "exchange_routing_inform";

    public static void main(String[] args) {
        Connection connection = null;
        Channel channel = null;
        try {
            //Create a connection to MQ
            ConnectionFactory factory = new ConnectionFactory();
            factory.setHost("127.0.0.1");
            factory.setPort(5672);
            factory.setUsername("guest");
            factory.setPassword("guest");
            factory.setVirtualHost("/");//rabbitmq default virtual machine name is "/", virtual machine is equivalent to an independent mq server
            //Create a connection
            connection = factory.newConnection();
            //Create channels with the switch, each representing a session
            channel = connection.createChannel();
            //Declare switch string exchange, builtinexchangetype
            /**
             * Parameter details
             *  1,Switch name
             *  2,Switch type, fanout, topic, direct, headers
             */
            channel.exchangeDeclare(EXCHANGE_ROUTING_INFORM, BuiltinExchangeType.DIRECT);
            //Declaration queue
            // channel.queueDeclare(String queue, boolean durable, boolean exclusive, booleanautoDelete, Map<String, Object> arguments)
            /**
             * Parameter details:
             *  1,Queue name
             *  2,Persistence or not
             *  3,Is this queue exclusive
             *  4,Queue does not need to be deleted automatically
             *  5,parameter
             */
            channel.queueDeclare(QUEUE_INFORM_EMAIL, true, false, false, null);
            channel.queueDeclare(QUEUE_INFORM_SMS, true, false, false, null);
            //Switch and queue binding String queue, String exchange, String routingKey
            /**
             * Parameter details
             *  1,Queue name
             *  2,Switch name
             *  3,Routing key
             */
            channel.queueBind(QUEUE_INFORM_EMAIL, EXCHANGE_ROUTING_INFORM, QUEUE_INFORM_EMAIL);
            channel.queueBind(QUEUE_INFORM_SMS, EXCHANGE_ROUTING_INFORM, QUEUE_INFORM_SMS);
            //send mail message
            for (int i = 0; i < 10; i++) {
                String message = "email inform to user" + i;
                //Send message String exchange, String routingKey, BasicProperties props,byte[] body to switch
                /**
                 * Parameter details
                 * 1,Switch name, do not instruct to use default switch name Default Exchange
                 * 2,routingKey(Route key). Forward the message to the specific queue according to the key name. Fill in the queue name here to indicate cancellation
                 Messages will be sent to this queue
                 * 3,Message attribute
                 * 4,Message content
                 */
                channel.basicPublish(EXCHANGE_ROUTING_INFORM, QUEUE_INFORM_EMAIL, null, message.getBytes());
                System.out.println("Send Message is:'" + message + "'");
            }
            //Send SMS message
            for (int i = 0; i < 10; i++) {
                String message = "sms inform to user" + i;
                //Send message String exchange, String routingKey, BasicProperties props,byte[] body to switch
                channel.basicPublish(EXCHANGE_ROUTING_INFORM, QUEUE_INFORM_SMS, null, message.getBytes());
                System.out.println("Send Message is:'" + message + "'");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        } finally {
            if (channel != null) {
                try {
                    channel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (TimeoutException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
  • Consumer test code
package com.rabbitmq.test;

import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class Consumer03_routing_email {
    //Queue name
    private static final String QUEUE_INFORM_EMAIL = "inform_queue_email";
    private static final String EXCHANGE_ROUTING_INFORM = "inform_exchange_routing";

    public static void main(String[] args) throws IOException, TimeoutException {
        //Create a connection to MQ
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("127.0.0.1");
        factory.setPort(5672);
        factory.setUsername("guest");
        factory.setPassword("guest");
        factory.setVirtualHost("/");//rabbitmq default virtual machine name is "/", virtual machine is equivalent to an independent mq server
        //Create a connection
        Connection connection = factory.newConnection();
        //Create channels with the switch, each representing a session
        Channel channel = connection.createChannel();
        //Declare switch string exchange, builtinexchangetype
        /**
         * Parameter details
         *  1,Switch name
         *  2,Switch type, fanout, topic, direct, headers
         */
        channel.exchangeDeclare(EXCHANGE_ROUTING_INFORM, BuiltinExchangeType.DIRECT);
        //Declaration queue
        // channel.queueDeclare(String queue, boolean durable, boolean exclusive, booleanautoDelete, Map < String, Object > arguments)
        /**
         * Parameter details:
         *  1,Queue name
         *  2,Persistence or not
         *  3,Is this queue exclusive
         *  4,Queue does not need to be deleted automatically
         *  5,parameter
         */
        channel.queueDeclare(QUEUE_INFORM_EMAIL, true, false, false, null);
        //Switch and queue binding String queue, String exchange, String routingKey
        /**
         * Parameter details
         *  1,Queue name
         *  2,Switch name
         *  3,Routing key
         */
        channel.queueBind(QUEUE_INFORM_EMAIL, EXCHANGE_ROUTING_INFORM, QUEUE_INFORM_EMAIL);
        //Define consumption method
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope,
                                       AMQP.BasicProperties properties, byte[] body) throws IOException {
                long deliveryTag = envelope.getDeliveryTag();
                String exchange = envelope.getExchange();
                //Message content
                String message = new String(body, "utf‐8");
                System.out.println(message);
            }
        };
        /**
         * Listening queue String queue, boolean autoAck,Consumer callback
         *
         * Parameter details
         *  1,Queue name
         *  2,Whether to reply automatically. If it is set to true, it means that the message has been automatically replied to mq when it is received. If it is set to false, you need to reply manually
         *  3,The method of consuming messages is called by consumers after receiving messages.
         */
        channel.basicConsume(QUEUE_INFORM_EMAIL, true, defaultConsumer);
    }
}

4. Topics

In Topics mode, each consumer listens to its own queue and sets a routingkey with a wildcard. The producer sends the message to the broker, and the switch forwards the message to the specified queue according to the routingkey.

  • Production side test code
    Declare the switch and specify the topic type:
package com.rabbitmq.test;

import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class Producer04_topics {
    //Queue name
    private static final String QUEUE_INFORM_EMAIL = "queue_inform_email";
    private static final String QUEUE_INFORM_SMS = "queue_inform_sms";
    private static final String EXCHANGE_TOPICS_INFORM = "exchange_topics_inform";

    public static void main(String[] args) {
        Connection connection = null;
        Channel channel = null;
        try {
            //Create a connection to MQ
            ConnectionFactory factory = new ConnectionFactory();
            factory.setHost("127.0.0.1");
            factory.setPort(5672);
            factory.setUsername("guest");
            factory.setPassword("guest");
            factory.setVirtualHost("/");//rabbitmq default virtual machine name is "/", virtual machine is equivalent to an independent mq server
            //Create a connection
            connection = factory.newConnection();
            //Create channels with the switch, each representing a session
            channel = connection.createChannel();
            //Declare switch string exchange, builtinexchangetype
            /**
             * Parameter details
             *  1,Switch name
             *  2,Switch type, fanout, topic, direct, headers
             */
            channel.exchangeDeclare(EXCHANGE_TOPICS_INFORM, BuiltinExchangeType.TOPIC);
            //Declaration queue
            /**
             * Parameter details:
             *  1,Queue name
             *  2,Persistence or not
             *  3,Is this queue exclusive
             *  4,Queue does not need to be deleted automatically
             *  5,parameter
             */
            channel.queueDeclare(QUEUE_INFORM_EMAIL, true, false, false, null);
            channel.queueDeclare(QUEUE_INFORM_SMS, true, false, false, null);
            //send mail message
            for (int i = 0; i < 10; i++) {
                String message = "email inform to user" + i;
                //Send message String exchange, String routingKey, BasicProperties props,byte[] body to switch
                /**
                 * Parameter details
                 *  1,Switch name, do not instruct to use default switch name Default Exchange
                 *  2,routingKey(Route key). Forward the message to a specific queue according to the key name. Fill in the queue name here to indicate that the message will be sent to this queue
                 *  3,Message attribute
                 *  4,Message content
                 */
                channel.basicPublish(EXCHANGE_TOPICS_INFORM, "inform.email", null,
                        message.getBytes());
                System.out.println("Send Message is:'" + message + "'");
            }
            //Send SMS message
            for (int i = 0; i < 10; i++) {
                String message = "sms inform to user" + i;
                channel.basicPublish(EXCHANGE_TOPICS_INFORM, "inform.sms", null,
                        message.getBytes());
                System.out.println("Send Message is:'" + message + "'");
            }
            //Send SMS and email messages
            for (int i = 0; i < 10; i++) {
                String message = "sms and email inform to user" + i;
                channel.basicPublish(EXCHANGE_TOPICS_INFORM, "inform.sms.email", null,
                        message.getBytes());
                System.out.println("Send Message is:'" + message + "'");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        } finally {
            if (channel != null) {
                try {
                    channel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (TimeoutException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
  • Consumer end
    Queue bound switches specify wildcards:
    Wildcard rule:
    Separated by "." in the middle.
    Symbol can match multiple words, symbol * can match one word.
//Declaration queue
channel.queueDeclare(QUEUE_INFORM_EMAIL, true, false, false, null);
channel.queueDeclare(QUEUE_INFORM_SMS, true, false, false, null);
//Claim switch
channel.exchangeDeclare(EXCHANGE_TOPICS_INFORM, BuiltinExchangeType.TOPIC);
//Bind email notification queue                                       
channel.queueBind(QUEUE_INFORM_EMAIL,EXCHANGE_TOPICS_INFORM,"inform.#.email.#");
//Bind sms notification queue
channel.queueBind(QUEUE_INFORM_SMS,EXCHANGE_TOPICS_INFORM,"inform.#.sms.#");

The Topic mode is more powerful. It can implement the functions of Routing and publish / sscirbe modes.

5. Header

The difference between the header mode and routing is that the header mode cancels the routing key and uses the key/value (key value pair) matching in the header
Don't talk much, go straight to the code

  • Production side test code
    The code of the binding between the queue and the switch is different as follows:
Map<String, Object> headers_email = new Hashtable<String, Object>();
headers_email.put("inform_type", "email");
Map<String, Object> headers_sms = new Hashtable<String, Object>();
headers_sms.put("inform_type", "sms");
channel.queueBind(QUEUE_INFORM_EMAIL,EXCHANGE_HEADERS_INFORM,"",headers_email);
channel.queueBind(QUEUE_INFORM_SMS,EXCHANGE_HEADERS_INFORM,"",headers_sms);

Notice:

String message = "email inform to user"+i;
Map<String,Object> headers = new Hashtable<String, Object>();
headers.put("inform_type", "email");//Match the header bound to the email notification consumer
//Headers. Put ("information_type", "sms"); / / match the header bound by sms notification consumer
AMQP.BasicProperties.Builder properties = new AMQP.BasicProperties.Builder();
properties.headers(headers);
//Email notification
channel.basicPublish(EXCHANGE_HEADERS_INFORM, "", properties.build(), message.getBytes());
  • Consumer test code
channel.exchangeDeclare(EXCHANGE_HEADERS_INFORM, BuiltinExchangeType.HEADERS);
Map<String, Object> headers_email = new Hashtable<String, Object>();
headers_email.put("inform_email", "email");
//Switch and queue binding
channel.queueBind(QUEUE_INFORM_EMAIL,EXCHANGE_HEADERS_INFORM,"",headers_email);
//Specify consumption queue
channel.basicConsume(QUEUE_INFORM_EMAIL, true, consumer);
6. RPC

RPC mode is the method that the client calls the server remotely. MQ can be used to realize the asynchronous call of RPC, which is based on the Direct switch. The process is as follows:

  1. The client is the producer and the consumer, sending RPC call messages to the RPC request queue and listening to the RPC response queue at the same time.
  2. The server listens for the message of RPC request queue, executes the method of the server after receiving the message, and gets the result returned by the method
  3. The server sends the result of RPC method to RPC response queue
  4. The client (RPC caller) listens to the RPC response queue and receives the RPC call result.
In our daily development, RPC mode is rarely used, and the Header mode is usually used most
Published 1 original article, praised 0, visited 6
Private letter follow

Posted by websiteguy on Wed, 29 Jan 2020 03:56:06 -0800