[learning companion] rabitmq notes of rabitmq (simply use rabitmq)

Posted by s0me0ne on Tue, 07 Sep 2021 01:02:52 +0200

catalogue

What is rabbitMQ

Install RabbitMQ with docker. If you haven't used docker, you can see this article https://blog.csdn.net/qq_44716544/article/details/119870837

Authorized account and password

Set user assigned operation permissions

Message model supported by RabbitMQ

1. Introduction case

1. RabbitMQ introduction case - Simple mode

2. What is AMQP

01 what is AMQP

02 AMQP producer flow process

03 AMQP consumer circulation process

3. The core components of rabbitmq

01 RabbitMQ core components

02 what does the overall architecture of rabbitmq look like?

03 operation process of rabbitmq

4. RabbitMQ entry case - fanout mode

01 publish subscribe mode of rabbitmq

5. RabbitMQ entry case - Direct mode

6. RabbitMQ introduction case - Topic mode

Complete case (create switch, create queue, and bind switch to queue)

7. RabbitMQ entry case - Work mode

01 Work mode polling mode (round robin)

01 polling mode

02 Work mode fair distribution mode  

8. RabbitMQ usage scenario

01 decoupling, peak shaving, asynchronous

02 high cohesion, low coupling

4, Springboot case

1. Fanout mode

2. Direct mode

3. Topic mode

5, RabbitMQ advanced

2. Dead letter queue

3. Memory disk monitoring

01 RabbitMQ memory warning

02 memory control of rabbitmq

03 RabbitMQ memory page feed

04 disk alert for rabbitmq

4. Cluster (docker cluster rabbitmq)

1. Create three rabbitmq containers first

2. The container node joins the cluster

What is rabbitMQ

  RabbitMQ is an open source implementation of AMQP (Advanced Message Queue protocol) developed by erlang, which can realize asynchronous message processing
  RabbitMQ is a message broker: it accepts and forwards messages.
You can think of it as a post office: when you put the mail you want to publish in the mailbox, you can make sure that the postman will finally send the mail to your recipient. In this metaphor, rabbit MQ is a post office box, a post office and a postman.  
The main difference between RabbitMQ and the post office is that it does not process paper, but accepts, stores and forwards binary data blocks
        
Advantages: asynchronous message processing
            Business decoupling (order placing operation: deduct inventory, generate order, send red envelope and send SMS). The main process of order placing operation: deduct inventory, generate order, and then complete notification through MQ message queue, send red envelope and send SMS
             Peak shifting flow control (MQ message queue mechanism is implemented when the number of notifications, messages and orders is large, and the traffic will be less in off-season)
        
               Flexible Routing  
              Route messages through Exchange before they enter the queue. For typical routing functions, RabbitMQ has provided some built-in Exchange to implement. For more complex routing functions, multiple exchanges can be bound together, and their own Exchange can be realized through plug-in mechanism.
         RabbitMQ website port number: 15672
         The port implemented in the program is: 5672

       

 

Install RabbitMQ with docker. If you haven't used docker, you can see this article https://blog.csdn.net/qq_44716544/article/details/119870837

1. Pull the RabbitMQ image

docker pull rabbitmq:management

2. Run RabbitMQ image

docker run -itd --name rabbit01 --hostname myrabbit -e RABBITMQ_DEFAULT_USER=chenjinxian -e RABBITMQ_DEFAULT_PASS=chenjinxian -p 15672:15672 -p  5672:5672 -p 25672:25672 rabbitmq:management

Note: RABBITMQ_DEFAULT_USER=chenjinxian -e RABBITMQ_DEFAULT_PASS=chenjinxian  

    Rabbitmq is set here_ DEFAULT_ User) login account and (rabbitmq)_ DEFAULT_ Pass) password, which can be modified according to itself

  Here you can see that the container has been opened successfully, and then it can be used

 

3. Open via browser

If you are using a local virtual machine, you can access it directly by using the ipv4 address displayed by the virtual machine plus the end slogan;

If you use ECs, you need to open port 15672 in the security group of the corresponding server (Alibaba cloud, Tencent cloud, etc.) and port 15672 in the firewall

 

  If the display is as shown in the figure above, you can start to use it

Then enter the rabbitmq container through the command

docker exec -it rabbit01 /bin/bash

Authorized account and password

rabbitmqctl add_user admin admin

Set user assigned operation permissions

rabbitmqctl set_user_tags admin administrator

User level:

  1. administrator: you can log in to the console, view all information, and manage rabbitmq

  2. monitoring: the monitor logs in to the console to view all information

  3. policymaker: the policy maker logs in to the console and specifies the policy

  4. Management common administrator login console

Add resource permissions for users

rabbitmqctl set_permissions -p / admin ".*"".*"".*"

You can also add users in the interface

 

Message model supported by RabbitMQ

1. Simple mode   

 

      2. Work ing mode

       

 

      3. Publish subscribe mode

  4. Routing mode

5. Topic mode

 

      6. Parameter mode

7. Publisher confirmation mode

 

1. Introduction case

1. RabbitMQ introduction case - Simple mode

  1. jdk1.8

  2. Build a maven project

  3. Define producer

  4. Define consumer

  5. Observe the process of the message in the rabbitmq server service

 

01 build a maven project

02 import dependency

 <dependencies>
        <!--Import rabbitmq Dependence of-->
        <dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>5.13.0</version>
        </dependency>

    </dependencies>

3. Coding  

  In the model above, there are the following concepts:

  1. The producer is the program that sends the message

  2. Consumer: the receiver of the message will always wait for the message to arrive.

  3. Message queue: the red part in the figure. Similar to a mailbox, messages can be cached; The producer delivers the message to it, and the consumer takes the message out of it.

producer

package com.chen.rabbitmq.simple;

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

/**
 * @description: Simple mode
 */
public class Producer {


    public static void main(String[] args) {

        // All middleware technologies are based on tcp/ip protocol to build a new protocol specification, but rabbitmq follows amqp
        // ip port

        // 1: Create connection project
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("128.197.157.151");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("chenjinxian");//rabbitmq login account
        connectionFactory.setPassword("chenjinxian");//rabbitmq login password
        connectionFactory.setVirtualHost("/");

        //springboot ---rabbitmq

        Connection connection = null;
        Channel channel = null;
        try {
            // 2: Why is the Connection Rabbitmq created based on channel rather than link? Long connection - channel
            connection = connectionFactory.newConnection("Generator");
            // 3: Get Channel through connection
            channel = connection.createChannel();
            // 4: Create switches, declare queues, bind relationships, route key s, send messages, and receive messages through communication
            String queueName = "queue1";

            /*
             * @params1 The name of the queue
             * @params2 Whether to persist durable=false. Whether to save the so-called persistent messages. If false is not persistent, true is persistent? Will non persistence be saved? The disk will be saved, but the service will be lost after restarting.
             * @params3 Exclusivity, is it exclusive independence
             * @params4 Whether to delete automatically. Whether to delete the queue automatically after the last consumer message is completed
             * @params5 Carry auxiliary parameters
             */
            channel.queueDeclare(queueName, true, false, false, null);
            // 5: Prepare message content
            String message = "Hello chenjinxian!!!";
            // 6: Send message to queue
            // @params1: switch @ params2 queue, routing key @params message status control @ params4 message subject
            // Interview question: can there be queues without switches? Impossible. Although no switch is specified, there must be a default switch.
            channel.basicPublish("", queueName, null, message.getBytes());

            System.out.println("Message sent successfully!!!");
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            // 7: Close channel
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            // 8: Close connection

            if (connection != null && connection.isOpen()) {
                try {
                    connection.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }


    }
}

 

 

consumer

package com.chen.rabbitmq.simple;

import com.rabbitmq.client.*;
import java.io.IOException;

public class Consumer {


    public static void main(String[] args) {

        // All middleware technologies are based on tcp/ip protocol to build a new protocol specification, but rabbitmq follows amqp
        // ip port

        // 1: Create connection project
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("128.197.157.151");//Server IP
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("chenjinxian");
        connectionFactory.setPassword("chenjinxian");
        connectionFactory.setVirtualHost("/");

        Connection connection = null;
        Channel channel = null;
        try {
            // 2: Create Connection
            connection = connectionFactory.newConnection("consumer");
            // 3: Get Channel through connection
            channel = connection.createChannel();
            // 4: Create switches, declare queues, bind relationships, route key s, send messages, and receive messages through communication


            // true = ack. The normal logic is no problem. The dead loop rabbit retransmission strategy
            // false = nack message, which may cause exceptions and failures when consuming messages
            final  Channel channel2 = channel;
            channel2.basicConsume("queue1", false, new DeliverCallback() {
                public void handle(String consumerTag, Delivery message) throws IOException {
                    try {
                        System.out.println("The message is" + new String(message.getBody(), "UTF-8"));
                        channel2.basicAck(message.getEnvelope().getDeliveryTag(),false);
                    }catch (Exception ex){
                        ex.printStackTrace();
                        // Three confirmations -- reject + sixin
                    }

                }
            }, new CancelCallback() {
                public void handle(String consumerTag) throws IOException {
                    System.out.println("Acceptance failed...");
                }
            });

            System.out.println("Start receiving messages");
            System.in.read();

        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            // 7: Close channel
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            // 8: Close connection

            if (connection != null && connection.isOpen()) {
                try {
                    connection.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }


    }
}

 

2. What is AMQP

01 what is AMQP

Full name of AMQP: Advanced Message Queuing Protocol. It is a development standard of application layer protocol and is designed for message oriented middleware

02 AMQP producer flow process

 

03 AMQP consumer circulation process

 

3. The core components of rabbitmq

01 RabbitMQ core components

 

Core concepts: core concepts:
Server: also known as Broker, it accepts client connections and implements AMQP entity services. Install rabbitmq serverconnection: connection, network connection between application and Broker, TCP / IP / three handshakes and four handshakes server: also known as Broker, which accepts client connections and implements AMQP entity services. Install rabbitmq serverconnection: connection, network connection between application and Broker, TCP / IP / three handshakes and four waves
Channel: network channel. Almost all operations are carried out in the channel. The channel is a channel for incoming reading and writing. The client can establish a pair of channels. Each channel represents a session task. Channel: network channel. Almost all operations are performed in the channel. The channel is a channel for incoming reading and writing. The client can establish a pair of channels. Each channel represents a session task channel.
Message: Message: the data transmitted between the service and the application. It is composed of properties and body. Properties can modify the message, such as message priority, delay and other advanced features. Body is the content of the message body. Message: Message: the data transmitted between the service and the application. It is composed of properties and body. Properties can modify the message, such as message priority, delay and other advanced features. Body is the content of the message body.
The Virtual Host virtual address is used for logical isolation and message routing at the top layer. A Virtual Host can have several exits and queues. The same Virtual Host cannot have virtual addresses of Exchange virtual hosts with the same name for logical isolation. A Virtual Host can have several exits and queues for message routing at the top layer, The same Virtual Host cannot have Exchange with the same name
Exchange: a switch that accepts messages and sends messages to a bound Queue according to the routing key. (== Does not have the ability to store messages = =) bindings: a virtual connection between exchange and Queue. Multiple routing keys can be protected in binding. Exchange: a switch that accepts messages and sends messages to the bound Queue according to the routing keys. (= does not have the ability to store messages = =) binding: a virtual connection between exchange and Queue. Multiple routing keys can be protected in binding.
Routing key: a routing rule that the virtual machine can use to determine how to route a special consumer. Bttos: / bloq.csdn.net/qg_ 4485823 (queue: queue: also known as Message Queue, Message Queue, save messages and forward them to the consumer“ gwa "routing key: it is a routing rule that the virtual machine can use to determine how to route a characteristic message (queue: queue: also known as Message Queue, Message Queue, save messages and forward them to consumers

 

02 what does the overall architecture of rabbitmq look like?

03 operation process of rabbitmq

 

 

4. RabbitMQ entry case - fanout mode

01 publish subscribe mode of rabbitmq

 

Implementation of publish subscribe mode

  1. Type: fanout

  2. Features: Fanout - publish and subscribe mode is a broadcast mechanism. It is a mode without routing key

(note that the queue has been bound to the switch in the visual interface)

 

producer

package com.chen.rabbitmq.fanout;

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

/**
 Implementation of publish subscribe mode
 Type: fanout
 Features: Fanout - publish and subscribe mode is a broadcast mechanism. It is a mode without routing key
 */
public class Producer {
    public static void main(String[] args) {
        // 1: Create connection factory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        // 2: Set connection properties
        connectionFactory.setHost("128.156.157.161");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("chenjinxian");
        connectionFactory.setPassword("chenjinxian");
        Connection connection = null;
        Channel channel = null;
        try {
            // 3: Get connection from connection factory
            connection = connectionFactory.newConnection("producer");
            // 4: Get channel from connection
            channel = connection.createChannel();

            // 5: Prepare to send the contents of the message
            String message = "hello xuexi!!!";

            // 6: Prepare switch
            String exchangeName = "fanout_change";

            // 8: Specifies the type of switch
            String type = "fanout";
            // 7: Send a message to the middleware rabbitmq server
            // @params1: switch exchange
            // @params2: queue name / routingkey
            // @params3: property configuration
            // @params4: send message content
            //  #.course.* queue3
            // *.order.# queue2 ta
            // com.order.course.xxx collecion
            channel.basicPublish(exchangeName,"", null, message.getBytes());


            System.out.println("Message sent successfully!");
        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("Exception in sending message...");
        } finally {

            // 7: Release connection close channel
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}

consumer

package com.chen.rabbitmq.fanout;

import com.rabbitmq.client.*;

import java.io.IOException;

/**
 Implementation of publish subscribe mode
 Type: fanout
 Features: Fanout - publish and subscribe mode is a broadcast mechanism. It is a mode without routing key
 */
public class Consumer {

    private static Runnable runnable = new Runnable() {
        public void run() {
            // 1: Create connection factory
            ConnectionFactory connectionFactory = new ConnectionFactory();
            // 2: Set connection properties
            connectionFactory.setHost("128.156.157.151");
            connectionFactory.setPort(5672);
            connectionFactory.setVirtualHost("/");
            connectionFactory.setUsername("chenjinxian");
            connectionFactory.setPassword("chenjinxian");
            //Gets the name of the queue
            final String queueName = Thread.currentThread().getName();
            Connection connection = null;
            Channel channel = null;
            try {
                // 3: Get connection from connection factory
                connection = connectionFactory.newConnection("producer");
                // 4: Get channel from connection
                channel = connection.createChannel();
                // 5: Declare that the queue stores messages
                /*
                 *  If the queue does not exist, it is created
                 *  Rabbitmq It is not allowed to create two identical queue names, otherwise an error will be reported.
                 *
                 *  @params1:  queue The name of the queue
                 *  @params2:  durable Is the queue persistent
                 *  @params3:  exclusive Exclusive, that is, private. If true, the current queue will be locked, other channels cannot be accessed, and the connection will be closed automatically
                 *  @params4:  autoDelete Whether to delete the message automatically, and whether to delete the message automatically after the last consumer disconnects.
                 *  @params5:  arguments You can set additional parameters of the queue, the validity period of the queue, the maximum length of messages, the message life cycle of the queue, and so on.
                 * */
                // Here, if the queue has been created once, it does not need to be defined
                //channel.queueDeclare("queue1", false, false, false, null);
                // 6: Defines a callback that accepts messages
                Channel finalChannel = channel;
                finalChannel.basicConsume(queueName, true, new DeliverCallback() {
                    @Override
                    public void handle(String s, Delivery delivery) throws IOException {
                        System.out.println(queueName + ": The message received is:" + new String(delivery.getBody(), "UTF-8"));
                    }
                }, new CancelCallback() {
                    @Override
                    public void handle(String s) throws IOException {
                    }
                });
                System.out.println(queueName + ": Start receiving messages");
                System.in.read();
            } catch (Exception ex) {
                ex.printStackTrace();
                System.out.println("Exception in sending message...");
            } finally {
                // 7: Release connection close channel
                if (channel != null && channel.isOpen()) {
                    try {
                        channel.close();
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
                if (connection != null && connection.isOpen()) {
                    try {
                        connection.close();
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            }
        }
    };



    public static void main(String[] args) {
        // Start three threads to execute
        new Thread(runnable, "queue1").start();
        new Thread(runnable, "queue2").start();
        new Thread(runnable, "queue3").start();
        new Thread(runnable, "queue4").start();
        //new Thread(runnable, "queue5").start();
    }
}

 

 

5. RabbitMQ entry case - Direct mode

 ( Note that the queue has been bound to the switch in the visual interface)

producer

package com.chen.rabbitmq.routing;

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

/**
 Direct pattern
 */
public class Producer {
    public static void main(String[] args) {
        // 1: Create connection factory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        // 2: Set connection properties
        connectionFactory.setHost("128.176.157.151");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("chenjinxian");
        connectionFactory.setPassword("chenjinxian");
        Connection connection = null;
        Channel channel = null;
        try {
            // 3: Get connection from connection factory
            connection = connectionFactory.newConnection("producer");
            // 4: Get channel from connection
            channel = connection.createChannel();

            // 5: Prepare to send the contents of the message
            String message = "hello direct_exchange!!!";

            // 6: Prepare switch
            String exchangeName = "direct_exchange";
            // 7: Define routing key
            String routeKey = "email";
            // 8: Specifies the type of switch
            String type = "direct";
            // 7: Send a message to the middleware rabbitmq server
            // @params1: switch exchange
            // @params2: queue name / routingkey
            // @params3: property configuration
            // @params4: send message content
            //  #.course.* queue3
            // *.order.# queue2 ta
            // com.order.course.xxx collecion
            channel.basicPublish(exchangeName, routeKey, null, message.getBytes());
            System.out.println("Message sent successfully!");
        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("Exception in sending message...");
        } finally {
            // 7: Release connection close channel
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}

consumer

package com.chen.rabbitmq.routing;

import com.rabbitmq.client.*;

import java.io.IOException;

/**
 Direct pattern
 */
public class Consumer {

    private static Runnable runnable = new Runnable() {
        public void run() {
            // 1: Create connection factory
            ConnectionFactory connectionFactory = new ConnectionFactory();
            // 2: Set connection properties
            connectionFactory.setHost("123.156.147.151");
            connectionFactory.setPort(5672);
            connectionFactory.setVirtualHost("/");
            connectionFactory.setUsername("chenjinxian");
            connectionFactory.setPassword("chenjinxian");
            //Gets the name of the queue
            final String queueName = Thread.currentThread().getName();
            Connection connection = null;
            Channel channel = null;
            try {
                // 3: Get connection from connection factory
                connection = connectionFactory.newConnection("producer");
                // 4: Get channel from connection
                channel = connection.createChannel();
                // 5: Declare that the queue stores messages
                /*
                 *  If the queue does not exist, it is created
                 *  Rabbitmq It is not allowed to create two identical queue names, otherwise an error will be reported.
                 *
                 *  @params1:  queue The name of the queue
                 *  @params2:  durable Is the queue persistent
                 *  @params3:  exclusive Exclusive, that is, private. If true, the current queue will be locked, other channels cannot be accessed, and the connection will be closed automatically
                 *  @params4:  autoDelete Whether to delete the message automatically, and whether to delete the message automatically after the last consumer disconnects.
                 *  @params5:  arguments You can set additional parameters of the queue, the validity period of the queue, the maximum length of messages, the message life cycle of the queue, and so on.
                 * */
                // Here, if the queue has been created once, it does not need to be defined
                //channel.queueDeclare("queue1", false, false, false, null);
                // 6: Defines a callback that accepts messages
                Channel finalChannel = channel;
                finalChannel.basicConsume(queueName, true, new DeliverCallback() {
                    @Override
                    public void handle(String s, Delivery delivery) throws IOException {
                        System.out.println(queueName + ": The message received is:" + new String(delivery.getBody(), "UTF-8"));
                    }
                }, new CancelCallback() {
                    @Override
                    public void handle(String s) throws IOException {
                    }
                });
                System.out.println(queueName + ": Start receiving messages");
                System.in.read();
            } catch (Exception ex) {
                ex.printStackTrace();
                System.out.println("Exception in sending message...");
            } finally {
                // 7: Release connection close channel
                if (channel != null && channel.isOpen()) {
                    try {
                        channel.close();
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
                if (connection != null && connection.isOpen()) {
                    try {
                        connection.close();
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            }
        }
    };



    public static void main(String[] args) {
        // Start three threads to execute
        new Thread(runnable, "queue1").start();
        new Thread(runnable, "queue2").start();
        new Thread(runnable, "queue3").start();
        new Thread(runnable, "queue4").start();
      //  new Thread(runnable, "queue5").start();
    }
}

6. RabbitMQ introduction case - Topic mode

  ( Note that the queue has been bound to the switch in the visual interface)

  producer

package com.chen.rabbitmq.topics;

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

/**
 Topic pattern
 */
public class Producer {
    public static void main(String[] args) {
        // 1: Create connection factory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        // 2: Set connection properties
        connectionFactory.setHost("125.156.157.151");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("chenjinxian");
        connectionFactory.setPassword("chenjinxian");
        Connection connection = null;
        Channel channel = null;
        try {
            // 3: Get connection from connection factory
            connection = connectionFactory.newConnection("producer");
            // 4: Get channel from connection
            channel = connection.createChannel();

            // 5: Prepare to send the contents of the message
            String message = "hello topic_exchange!!!";

            // 6: Prepare switch
            String exchangeName = "topic_exchange";
            // 7: Define routing key
            String routeKey = "com.order.user";
            // 8: Specifies the type of switch
            String type = "topic";
            // 7: Send a message to the middleware rabbitmq server
            // @params1: switch exchange
            // @params2: queue name / routingkey
            // @params3: property configuration
            // @params4: send message content
            //  #.course.* queue3
            // *.order.# queue2 ta
            // com.order.course.xxx collecion
            channel.basicPublish(exchangeName, routeKey, null, message.getBytes());
            System.out.println("Message sent successfully!");
        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("Exception in sending message...");
        } finally {
            // 7: Release connection close channel
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}

  Consumer unchanged

Complete case (create switch, create queue, and bind switch to queue)

package com.chen.rabbitmq.all;

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

/**
Complete case
 */
public class Producer {
    public static void main(String[] args) {
        // 1: Create connection factory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        // 2: Set connection properties
        connectionFactory.setHost("151.156.157.151");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("chenjinxian");
        connectionFactory.setPassword("chenjinxian");
        Connection connection = null;
        Channel channel = null;
        try {
            // 3: Get connection from connection factory
            connection = connectionFactory.newConnection("producer");
            // 4: Get channel from connection
            channel = connection.createChannel();
            // 6: Prepare to send the contents of the message
            String message = " Hello, Xiaobai";
            // Switch
            String  exchangeName = "direct_message_exchange";
            // Type of switch: direct/topic/fanout/headers
            String exchangeType = "direct";

            // If you use the interface to bind the relationship between queueu and exchange first, you don't need to write these declaration codes, which can make the code more concise, but it can't be read
            // If we declare it in code, we need to learn
            // 7: The so-called persistence of the switch means whether the switch will be lost with the server restart. If true means no loss, false restart will be lost
            channel.exchangeDeclare(exchangeName,exchangeType,true);

            // 8: Declaration queue
            channel.queueDeclare("queue5",true,false,false,null);
            channel.queueDeclare("queue6",true,false,false,null);
            channel.queueDeclare("queue7",true,false,false,null);

            // 9: Relationship between binding queue and switch
            channel.queueBind("queue5",exchangeName,"order");
            channel.queueBind("queue6",exchangeName,"order");
            channel.queueBind("queue7",exchangeName,"course");

            channel.basicPublish(exchangeName, "course", null, message.getBytes());
            System.out.println("Message sent successfully!");
        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("Exception in sending message...");
        } finally {
            // 7: Release connection close channel
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}

  Generate queues and switches after execution

 

 

7. RabbitMQ entry case - Work mode

01 Work mode polling mode (round robin)

 

When there are multiple consumers, which consumer will consume our news, and how can we balance the amount of consumer consumption information?

There are two main modes:

  1. Distribution in polling mode: one for each consumer, distributed equally

  2. Fair distribution: fair distribution is carried out according to the consumption capacity of consumers, with more fast processing and less slow processing; distribution according to work

01 polling mode

producer

package com.chen.rabbitmq.work.lunxun;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
/**
 Polling mode
 */
public class Producer {
    public static void main(String[] args) {
        // 1: Create connection factory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        // 2: Set connection properties
        connectionFactory.setHost("123.156.147.151");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("chenjinxian");
        connectionFactory.setPassword("chenjinxian");
        Connection connection = null;
        Channel channel = null;
        try {
            // 3: Get connection from connection factory
            connection = connectionFactory.newConnection("producer");
            // 4: Get channel from connection
            channel = connection.createChannel();
            // 6: Prepare to send the contents of the message
            //===============================end topic mode==================================
            for (int i = 1; i <= 20; i++) {
                //Content of the message
                String msg = "Learning companion:" + i;
                // 7: Send a message to the middleware rabbitmq server
                // @params1: switch exchange
                // @params2: queue name / routingkey
                // @params3: property configuration
                // @params4: send message content
                channel.basicPublish("", "queue1", null, msg.getBytes());
            }
            System.out.println("Message sent successfully!");
        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("Exception in sending message...");
        } finally {
            // 7: Release connection close channel
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}

consumer

package com.chen.rabbitmq.work.lunxun;
import com.rabbitmq.client.*;
import java.io.IOException;
/**
 Polling mode
 */
public class Work1 {
    public static void main(String[] args) {
        // 1: Create connection factory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        // 2: Set connection properties
        connectionFactory.setHost("123.156.147.155");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("chenjinxian");
        connectionFactory.setPassword("chenjinxian");
        Connection connection = null;
        Channel channel = null;
        try {
            // 3: Get connection from connection factory
            connection = connectionFactory.newConnection("consumer-Work1");
            // 4: Get channel from connection
            channel = connection.createChannel();
            // 5: Declare that the queue stores messages
            /*
             *  If the queue does not exist, it is created
             *  Rabbitmq It is not allowed to create two identical queue names, otherwise an error will be reported.
             *
             *  @params1:  queue The name of the queue
             *  @params2:  durable Is the queue persistent
             *  @params3:  exclusive Exclusive, that is, private. If true, the current queue will be locked, other channels cannot be accessed, and the connection will be closed automatically
             *  @params4:  autoDelete Whether to delete the message automatically, and whether to delete the message automatically after the last consumer disconnects.
             *  @params5:  arguments You can set additional parameters of the queue, the validity period of the queue, the maximum length of messages, the message life cycle of the queue, and so on.
             * */
            // Here, if the queue has been created once, it does not need to be defined
//            channel.queueDeclare("queue1", false, false, false, null);
            // At the same time, the server will only push one message to the consumer
            // 6: Defines a callback that accepts messages
            Channel finalChannel = channel;
            //finalChannel.basicQos(1);

            finalChannel.basicConsume("queue1", true, new DeliverCallback() {
                @Override
                public void handle(String s, Delivery delivery) throws IOException {
                    try{
                        System.out.println("Work1-The message received is:" + new String(delivery.getBody(), "UTF-8"));
                        Thread.sleep(200);
                    }catch(Exception ex){
                        ex.printStackTrace();
                    }
                }
            }, new CancelCallback() {
                @Override
                public void handle(String s) throws IOException {
                }
            });
            System.out.println("Work1-Start receiving messages");
            System.in.read();
        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("Exception in sending message...");
        } finally {
            // 7: Release connection close channel
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            if (connection != null && connection.isOpen()) {
                try {
                    connection.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}
package com.chen.rabbitmq.work.lunxun;
import com.rabbitmq.client.*;
import java.io.IOException;
/**
 Polling mode
 */
public class Work2 {
    public static void main(String[] args) {
        // 1: Create connection factory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        // 2: Set connection properties
        connectionFactory.setHost("123.195.157.151");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("chenjinxian");
        connectionFactory.setPassword("chenjinxian");
        Connection connection = null;
        Channel channel = null;
        try {
            // 3: Get connection from connection factory
            connection = connectionFactory.newConnection("consumer-Work2");
            // 4: Get channel from connection
            channel = connection.createChannel();
            // 5: Declare that the queue stores messages
            /*
             *  If the queue does not exist, it is created
             *  Rabbitmq It is not allowed to create two identical queue names, otherwise an error will be reported.
             *
             *  @params1:  queue The name of the queue
             *  @params2:  durable Is the queue persistent
             *  @params3:  exclusive Exclusive, that is, private. If true, the current queue will be locked, other channels cannot be accessed, and the connection will be closed automatically
             *  @params4:  autoDelete Whether to delete the message automatically, and whether to delete the message automatically after the last consumer disconnects.
             *  @params5:  arguments You can set additional parameters of the queue, the validity period of the queue, the maximum length of messages, the message life cycle of the queue, and so on.
             * */
            // Here, if the queue has been created once, it does not need to be defined
            //channel.queueDeclare("queue1", false, true, false, null);
            // At the same time, the server will only push one message to the consumer
            //channel.basicQos(1);
            // 6: Defines a callback that accepts messages
            Channel finalChannel = channel;
            //finalChannel.basicQos(1);
            finalChannel.basicConsume("queue1", true, new DeliverCallback() {
                @Override
                public void handle(String s, Delivery delivery) throws IOException {
                    try{
                        System.out.println("Work2-The message received is:" + new String(delivery.getBody(), "UTF-8"));
                        Thread.sleep(100);
                    }catch(Exception ex){
                        ex.printStackTrace();
                    }
                }
            }, new CancelCallback() {
                @Override
                public void handle(String s) throws IOException {
                }
            });
            System.out.println("Work2-Start receiving messages");
            System.in.read();
        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("Exception in sending message...");
        } finally {
            // 7: Release connection close channel
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            if (connection != null && connection.isOpen()) {
                try {
                    connection.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}

 

02 Work mode fair distribution mode  

producer

package com.chen.rabbitmq.work.fair;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

/**
 Fair distribution model
 */
public class Producer {
    public static void main(String[] args) {
        // 1: Create connection factory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        // 2: Set connection properties
        connectionFactory.setHost("125.156.157.151");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("chenjinxian");
        connectionFactory.setPassword("chenjinxian");
        Connection connection = null;
        Channel channel = null;
        try {
            // 3: Get connection from connection factory
            connection = connectionFactory.newConnection("producer");
            // 4: Get channel from connection
            channel = connection.createChannel();
            // 6: Prepare to send the contents of the message
            //===============================end topic mode==================================
            for (int i = 1; i <= 20; i++) {
                //Content of the message
                String msg = "Learning companion:" + i;
                // 7: Send a message to the middleware rabbitmq server
                // @params1: switch exchange
                // @params2: queue name / routingkey
                // @params3: property configuration
                // @params4: send message content
                channel.basicPublish("", "queue1", null, msg.getBytes());
            }
            System.out.println("Message sent successfully!");
        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("Exception in sending message...");
        } finally {
            // 7: Release connection close channel
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}

consumer

package com.chen.rabbitmq.work.fair;

import com.rabbitmq.client.*;

import java.io.IOException;

/**
 Fair distribution model
 */
public class Work1 {
    public static void main(String[] args) {
        // 1: Create connection factory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        // 2: Set connection properties
        connectionFactory.setHost("123.156.146.151");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("chenjinxian");
        connectionFactory.setPassword("chenjinxian");
        Connection connection = null;
        Channel channel = null;
        try {
            // 3: Get connection from connection factory
            connection = connectionFactory.newConnection("consumer-Work1");
            // 4: Get channel from connection
            channel = connection.createChannel();
            // 5: Declare that the queue stores messages
            /*
             *  If the queue does not exist, it is created
             *  Rabbitmq It is not allowed to create two identical queue names, otherwise an error will be reported.
             *
             *  @params1:  queue The name of the queue
             *  @params2:  durable Is the queue persistent
             *  @params3:  exclusive Exclusive, that is, private. If true, the current queue will be locked, other channels cannot be accessed, and the connection will be closed automatically
             *  @params4:  autoDelete Whether to delete the message automatically, and whether to delete the message automatically after the last consumer disconnects.
             *  @params5:  arguments You can set additional parameters of the queue, the validity period of the queue, the maximum length of messages, the message life cycle of the queue, and so on.
             * */
            // Here, if the queue has been created once, it does not need to be defined
//            channel.queueDeclare("queue1", false, false, false, null);
            // At the same time, the server will only push one message to the consumer
            // 6: Defines a callback that accepts messages
            final Channel finalChannel = channel;
            
            finalChannel.basicQos(1);
            finalChannel.basicConsume("queue1", false, new DeliverCallback() {
                @Override
                public void handle(String s, Delivery delivery) throws IOException {
                    try{
                        System.out.println("Work1-The message received is:" + new String(delivery.getBody(), "UTF-8"));
                        Thread.sleep(1000);
                        // Change to manual response
                        finalChannel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
                    }catch(Exception ex){
                        ex.printStackTrace();
                    }
                }
            }, new CancelCallback() {
                @Override
                public void handle(String s) throws IOException {
                }
            });
            System.out.println("Work1-Start receiving messages");
            System.in.read();
        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("Exception in sending message...");
        } finally {
            // 7: Release connection close channel
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            if (connection != null && connection.isOpen()) {
                try {
                    connection.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}
package com.chen.rabbitmq.work.fair;

import com.rabbitmq.client.*;

import java.io.IOException;

/**
 Fair distribution model
 */
public class Work2 {
    public static void main(String[] args) {
        // 1: Create connection factory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        // 2: Set connection properties
        connectionFactory.setHost("121.156.157.131");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("chenjinxian");
        connectionFactory.setPassword("chenjinxian");
        Connection connection = null;
        Channel channel = null;
        try {
            // 3: Get connection from connection factory
            connection = connectionFactory.newConnection("consumer-Work2");
            // 4: Get channel from connection
            channel = connection.createChannel();
            // 5: Declare that the queue stores messages
            /*
             *  If the queue does not exist, it is created
             *  Rabbitmq It is not allowed to create two identical queue names, otherwise an error will be reported.
             *
             *  @params1:  queue The name of the queue
             *  @params2:  durable Is the queue persistent
             *  @params3:  exclusive Exclusive, that is, private. If true, the current queue will be locked, other channels cannot be accessed, and the connection will be closed automatically
             *  @params4:  autoDelete Whether to delete the message automatically, and whether to delete the message automatically after the last consumer disconnects.
             *  @params5:  arguments You can set additional parameters of the queue, the validity period of the queue, the maximum length of messages, the message life cycle of the queue, and so on.
             * */
            // Here, if the queue has been created once, it does not need to be defined
            //channel.queueDeclare("queue1", false, true, false, null);
            // At the same time, the server will only push one message to the consumer
            //channel.basicQos(1);
            // 6: Defines a callback that accepts messages
            final Channel finalChannel = channel;
            finalChannel.basicQos(1);
            finalChannel.basicConsume("queue1", false, new DeliverCallback() {
                @Override
                public void handle(String s, Delivery delivery) throws IOException {
                    try{
                        System.out.println("Work2-The message received is:" + new String(delivery.getBody(), "UTF-8"));
                        Thread.sleep(200);
                        // Be sure to use our manual answer
                        finalChannel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
                    }catch(Exception ex){
                        ex.printStackTrace();
                    }
                }
            }, new CancelCallback() {
                @Override
                public void handle(String s) throws IOException {
                }
            });
            System.out.println("Work2-Start receiving messages");
            System.in.read();
        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("Exception in sending message...");
        } finally {
            // 7: Release connection close channel
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            if (connection != null && connection.isOpen()) {
                try {
                    connection.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}

8. RabbitMQ usage scenario

 

01 decoupling, peak shaving, asynchronous

 

Synchronous asynchronous problem (serial)

Serial mode: after successfully writing the order information into the database, send the registration email and then send the registration SMS. After the above three tasks are completed, return to the client

 

Parallel asynchronous thread pool

Parallel mode: after the order information is successfully written into the database, send the registration email and send the registration SMS at the same time. After the above three tasks are completed, return to the client. The difference from serial is that the parallel method can improve the processing time

Existing problems

  1. High coupling

  2. You need to write your own thread pool. The maintenance cost is too high

  3. Messages may be lost. You need to make message compensation yourself

  4. How to ensure the reliability of the message? Write it yourself

  5. If the server cannot be hosted, you need to write high availability

Asynchronous message queuing

 

 

Benefits:

  1. Fully decoupled, bridging with MQ

  2. There is an independent thread pool and running model

  3. If a message occurs, it may be lost. MQ has persistence function

  4. How to ensure the reliability of messages, dead letter queue and message transfer, etc

  5. If the server cannot be hosted, you need to write high availability, and the HA image model is high availability

According to the above agreement, the user's response time is equivalent to the time when the order information is written to the database, that is, 50 milliseconds. Register e-mail, send SMS, write to the message queue and return directly. Therefore, the speed of writing to the message queue is very fast and can be basically ignored. Therefore, the user's response time may be 50 milliseconds. Therefore, after the architecture is changed, the throughput of the system is increased to 20QPS per second. It is three times higher than serial and two times higher than parallel

 

02 high cohesion, low coupling

 

 

Benefits:

  1. Fully decoupled, bridging with MQ

  2. There is an independent thread pool and running model

  3. If a message occurs, it may be lost. MQ has persistence function

  4. How to ensure the reliability of messages, dead letter queue and message transfer, etc

  5. If the server cannot be hosted, you need to write high availability, and the HA image model is high availability

According to the above agreement, the user's response time is equivalent to the time when the order information is written to the database, that is, 50 milliseconds. Register e-mail, send SMS, write to the message queue and return directly. Therefore, the speed of writing to the message queue is very fast and can be basically ignored. Therefore, the user's response time may be 50 milliseconds. Therefore, after the architecture is changed, the throughput of the system is increased to 20QPS per second. It is three times higher than serial and two times higher than parallel

4, Springboot case

1. Fanout mode

producer

Import dependency

  <!--rabbitmq starter rely on-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>

application.yml

# Service port
server:
  port: 8080
# Configure rabbitmq service
spring:
	rabbitmq:
		username: admin
		password: admin
		virtual-host: /
		host: 127.0.0.1
		port: 5672

directory structure  

  Create configuration class RabbitMqConfiguration.java

package com.chen.springbootorderrabbitmqproducer.config;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**

 */
@Configuration
public class RabbitMqConfiguration {


    // 1: Claim switch
    @Bean
    public FanoutExchange fanoutExchange() {
        return new FanoutExchange("fanout_order_ex", true, false);
    }


    // 2: Declaration queue duanxin.fanout.queue
    @Bean
    public Queue duanxinqueue() {
        return new Queue("duanxin.fanout.queue", true);
    }


    // 2: Declaration queue duanxin.fanout.queue
    @Bean
    public Queue smsqueue() {
        return new Queue("sms.fanout.queue", true);
    }


    // 2: Declaration queue duanxin.fanout.queue
    @Bean
    public Queue emailqueue() {
        return new Queue("email.fanout.queue", true);
    }


    // 3: Determine binding relationship
    @Bean
    public Binding bindduanxin(){
        return BindingBuilder.bind(duanxinqueue()).to(fanoutExchange());
    }

    // 3: Determine binding relationship
    @Bean
    public Binding bindsms(){
        return BindingBuilder.bind(smsqueue()).to(fanoutExchange());
    }

    // 3: Determine binding relationship
    @Bean
    public Binding bindemail(){
        return BindingBuilder.bind(emailqueue()).to(fanoutExchange());
    }
}

  Write the implementation class OrderService.java

package com.chen.springbootorderrabbitmqproducer.service;

import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.UUID;

/**

 */
@Service
public class OrderService {
    
    @Autowired
    private RabbitTemplate rabbitTemplate;

    // Switch
    private String exchangeName = "fanout_order_ex";
    // Routing key
    private String routingKey = "";

    
    /**
     * @Author xuke
     * @Description Simulate the business of placing orders for goods purchased by users
     * @Date 22:26 2021/3/5
     * @Param [userId, productId, num]
     * @return void
    **/
    public void makeOrder(String userId,String productId,int num){
        // 1: Query whether the inventory is sufficient according to the commodity id
        // 2: Save order
        String orderId = UUID.randomUUID().toString();
        System.out.println("Order saved successfully: id Yes:" + orderId);
        // 3: Send message
        rabbitTemplate.convertAndSend(exchangeName,routingKey,orderId);
    }

}

Writing test classes

package com.chen.springbootorderrabbitmqproducer.rabbitmq.springbootorderrabbitmqproducer;


import com.chen.springbootorderrabbitmqproducer.service.OrderService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class SpringbootOrderRabbitmqProducerApplicationTests {


    @Autowired
    private OrderService orderService;


    @Test
    public void contextLoads() {
        orderService.makeOrder("100","100",10);
    }



    @Test
    public void testDirect() {
        orderService.makeOrderDirect("100","100",10);
    }

    @Test
    public void testDirectTTl() {
        orderService.makeOrderDirectTtl("100","100",10);
    }


//    @Test
//    public void testTopic() {
//        orderService.makeOrderTopic("100","100",10);
//    }

}

consumer

application.yml

# Service port
server:
  port: 8080
# Configure rabbitmq service
spring:
	rabbitmq:
		username: admin
		password: admin
		virtual-host: /
		host: 127.0.0.1
		port: 5672

Accept message

package com.chen.direct;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

/**
 
 */
@Service
@RabbitListener(queues ={"duanxin.direct.queue"})
public class DirectDuanxinConsumber {


    // The message that tells your receiving server has no return value
    @RabbitHandler
    public void reviceMessage(String message){
        System.out.println("duanxin--direct--->Order message received, order id yes: " + message);
    }
}
package com.chen.direct;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

/**

 */
@Service
@RabbitListener(queues ={"email.direct.queue"})
public class DirectEmailConsumber {


    @RabbitHandler
    public void reviceMessage(String message){
        System.out.println("email---direct-->Order message received, order id yes: " + message);
    }
}
package com.chen.direct;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

/**

 */
@Service
@RabbitListener(queues ={"sms.direct.queue"})
public class DirectSmsConsumber {


    @RabbitHandler
    public void reviceMessage(String message){
        System.out.println("sms--direct--->Order message received, order id yes: " + message);
    }
}

2. Direct mode

producer

Configuration class

package com.chen.springbootorderrabbitmqproducer.config;

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

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

/**

 */
@Configuration
public class RabbitMqConfiguration2 {


    // 1: Claim switch
    @Bean
    public DirectExchange directExchange() {
        return new DirectExchange("direct_order_ex", true, false);
    }


    // 2: Declaration queue duanxin.direct.queue
    @Bean
    public Queue duanxinqueue() {
        return new Queue("duanxin.direct.queue", true);
    }


    // 2: Declaration queue duanxin.direct.queue
    @Bean
    public Queue smsqueue() {
        return new Queue("sms.direct.queue", true);
    }


    // 2: Declaration queue duanxin.direct.queue
    @Bean
    public Queue emailqueue() {
        return new Queue("email.direct.queue", true);
    }



    // 3: Determine binding relationship
    @Bean
    public Binding bindduanxin(){
        return BindingBuilder.bind(duanxinqueue()).to(directExchange()).with("msg");
    }

    // 3: Determine binding relationship
    @Bean
    public Binding bindsms(){
        return BindingBuilder.bind(smsqueue()).to(directExchange()).with("sms");
    }

    // 3: Determine binding relationship
    @Bean
    public Binding bindemail(){
        return BindingBuilder.bind(emailqueue()).to(directExchange()).with("email");
    }
}

Implementation class:

package com.chen.springbootorderrabbitmqproducer.service;

import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.UUID;

/**

 */
@Service
public class OrderService {
    
    @Autowired
    private RabbitTemplate rabbitTemplate;

    // Switch
    private String exchangeName = "fanout_order_ex";
    // Routing key
    private String routingKey = "";

    
 


    /**
     * @Description Simulate the business of placing orders for goods purchased by users  
     * @Param [userId, productId, num]
     * @return void
     **/
    public void makeOrderDirect(String userId,String productId,int num){
        // 1: Query whether the inventory is sufficient according to the commodity id
        // 2: Save order
        String orderId = UUID.randomUUID().toString();
        System.out.println("Order saved successfully: id Yes:" + orderId);
        // 3: Send message
        rabbitTemplate.convertAndSend("direct_order_ex","email",orderId);
        rabbitTemplate.convertAndSend("direct_order_ex","sms",orderId);
    }

 




}

Test:

package com.chen.springbootorderrabbitmqproducer.rabbitmq.springbootorderrabbitmqproducer;


import com.chen.springbootorderrabbitmqproducer.service.OrderService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class SpringbootOrderRabbitmqProducerApplicationTests {

    @Autowired
    private OrderService orderService;


    @Test
    public void testDirect() {
        orderService.makeOrderDirect("100","100",10);
    }


}

consumer

package com.chen.direct;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

/**
 * @description:
 */
@Service
@RabbitListener(queues ={"duanxin.direct.queue"})
public class DirectDuanxinConsumber {


    // The message that tells your receiving server has no return value
    @RabbitHandler
    public void reviceMessage(String message){
        System.out.println("duanxin--direct--->Order message received, order id yes: " + message);
    }
}
package com.chen.direct;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

/**

 */
@Service
@RabbitListener(queues ={"email.direct.queue"})
public class DirectEmailConsumber {


    @RabbitHandler
    public void reviceMessage(String message){
        System.out.println("email---direct-->Order message received, order id yes: " + message);
    }
}
package com.chen.direct;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

/**

@Service
@RabbitListener(queues ={"sms.direct.queue"})
public class DirectSmsConsumber {


    @RabbitHandler
    public void reviceMessage(String message){
        System.out.println("sms--direct--->Order message received, order id yes: " + message);
    }
}

3. Topic mode

producer

public class OrderService{
    @Autowired
    private RabbitTemplate rabbitTemplate;
    //Simulated user orders
    public void makeOrder(String userid,String productid,int num){
  
  public void makeOrderTopic(String userId,String productId,int num){
        // 1: Query whether the inventory is sufficient according to the commodity id
        // 2: Save order
        String orderId = UUID.randomUUID().toString();
        System.out.println("Order saved successfully: id Yes:" + orderId);
        // 3: Send message

        //com.#  duanxin
        //#.email.* email
        //#.sms.# sms
        // Set message confirmation mechanism
        rabbitTemplate.convertAndSend("topic_order_ex","com.email.sms.xxx",orderId);
    }
}
 @Test
    public void testTopic() {
        orderService.makeOrderTopic("100","100",10);
    }

 

Consumer (using notes)

FanoutSmsConsumer.java

@Component
@RabbitListener(bindings = @QueueBinding(
	value = @Queue(value = "sms.topic.queue",durable = "true",antoDelete = "false"),
    exchange = @Exchange(value = "topic_order_exchange",type = "ExchangeTypes.TOPIC")
    key = "#.sms.#"
))
public class TopicSmsConsumer{
    @RabbitHandler
    public void reviceMessage(String message){
        sout("sms The order information received is:"+message);
    }
}

FanoutDuanxinConsumer.java

@Component
@RabbitListener(bindings = @QueueBinding(
	value = @Queue(value = "duanxin.topic.queue",durable = "true",antoDelete = "false"),
    exchange = @Exchange(value = "topic_order_exchange",type = "ExchangeTypes.TOPIC")
    key = "#.duanxin.#"
))
public classTopicDuanxinConsumer{
    @RabbitHandler
    public void reviceMessage(String message){
        sout("duanxin The order information received is:"+message);
    }
}

FanoutEmailConsumer.java

@Component
@RabbitListener(bindings = @QueueBinding(
	value = @Queue(value = "email.topic.queue",durable = "true",antoDelete = "false"),
    exchange = @Exchange(value = "topic_order_exchange",type = "ExchangeTypes.TOPIC")
    key = "#.email.#"
))
public class TopicEmailConsumer{
    @RabbitHandler
    public void reviceMessage(String message){
        sout("email The order information received is:"+message);
    }
}

5, RabbitMQ advanced

1. Expiration time TTL

summary

The expiration time TTL indicates that the expected time can be set for the message and can be received by the consumer within this time; After that, the message will be deleted automatically. RabbitMQ can set TTL for messages and queues. At present, there are two methods to set TTL

  1. The first method is to set the queue property so that all messages in the queue have the same expiration time

  2. The second method is to set the message separately, and the TTL of each message can be different

If the above two methods are used at the same time, the expiration time of the message shall be subject to the value with the smaller TTL. Once the lifetime of the message in the queue exceeds the set TTL value, it is called dead message. It is delivered to the dead letter queue, and the consumer will no longer receive the message

Set queue TTL

 RabbitMqConfiguration.java

@Configuration
public class TTLRabbitMQConfiguration{
    //1. Declare and register the switch in direct mode
    @Bean
    public DirectExchange ttldirectExchange(){
        return new DirectExchange("ttl_direct_exchange",true,false);}
    //2. Expiration time of the queue
    @Bean
    public Queue directttlQueue(){
        //Set expiration time
        Map<String,Object> args = new HashMap<>();
        args.put("x-message-ttl",5000);//This must be of type int
        return new Queue("ttl.direct.queue",true,false,false,args);}
    
    @Bean
    public Binding ttlBingding(){
        return BindingBuilder.bin(directttlQueue()).to(ttldirectExchange()).with("ttl");
    }
}

Set message TTL

public class OrderService{
    @Autowired
    private RabbitTemplate rabbitTemplate;
    //Simulated user orders
    public void makeOrder(String userid,String productid,int num){
        //1. Query whether the inventory is sufficient according to the commodity id
        //2. Save order
        String orderId = UUID.randomUUID().toString();
        sout("Order production succeeded:"+orderId);
        //3. Complete message distribution through MQ
        //Parameter 1: switch parameter 2: routing key/queue queue name parameter 3: message content
        String exchangeName = "ttl_order_exchange";
        String routingKey = "ttlmessage";
        //Set expiration time for messages
        MessagePostProcessor messagePostProcessor = new MessagePostProcessor(){
            public Message postProcessMessage(Message message){
                //Here is the string
                message.getMessageProperties().setExpiration("5000");
                message.getMessageProperties().setContentEncoding("UTF-8");
                return message;
            }
        }
        rabbitTemplate.convertAndSend(exchangeName,routingKey,orderId,messagePostProcessor);
    }
}

RabbitMqConfiguration.java

@Configuration
public class TTLRabbitMQConfiguration{
    //1. Declare and register the switch in direct mode
    @Bean
    public DirectExchange ttldirectExchange(){
        return new DirectExchange("ttl_direct_exchange",true,false);}
    //2. Expiration time of the queue
    @Bean
    public Queue directttlQueue(){
        //Set expiration time
        Map<String,Object> args = new HashMap<>();
        args.put("x-message-ttl",5000);//This must be of type int
        return new Queue("ttl.direct.queue",true,false,false,args);}
    @Bean
    public Queue directttlMessageQueue(){
        return new Queue("ttlMessage.direct.queue",true,false,false,args);}
    
    @Bean
    public Binding ttlBingding(){
        return BindingBuilder.bin(directttlMessageQueue()).to(ttldirectExchange()).with("ttlmessage");
    }
}

2. Dead letter queue

summary

DLX, fully known as dead letter exchange, can be called dead letter switch or dead letter mailbox. When a message becomes dead letter in another queue, it can be re sent to another switch, which is DLX. The queue bound to DLX is called dead letter queue. The message may become dead letter due to the following reasons:

  1. Message rejected

  2. Message expiration

  3. The queue has reached its maximum length

DLX is also a normal switch. It is no different from a general switch. It can be specified on any queue. In fact, it is to set the properties of a queue. When there is dead letter in this queue, Rabbitmq will automatically republish the message to the set DLX, and then route it to another queue, that is, dead letter queue.

To use dead letter queue, you only need to set the queue parameter x-dead-letter-exchange to specify the switch when defining the queue

code

DeadRabbitMqConfiguration.java

@Configuration
public class DeadRabbitMqConfiguration{
    //1. Declare and register the switch in direct mode
    @Bean
    public DirectExchange deadDirect(){
        return new DirectExchange("dead_direct_exchange",true,false);}
    //2. Expiration time of the queue
    @Bean
    public Queue deadQueue(){
        return new Queue("dead.direct.queue",true);}
    @Bean
    public Binding deadbinds(){
        return BindingBuilder.bind(deadDirect()).to(deadQueue()).with("dead");
    }
}

RabbitMqConfiguration.java

@Configuration
public class TTLRabbitMQConfiguration{
    //1. Declare and register the switch in direct mode
    @Bean
    public DirectExchange ttldirectExchange(){
        return new DirectExchange("ttl_direct_exchange",true,false);}
    //2. Expiration time of the queue
    @Bean
    public Queue directttlQueue(){
        //Set expiration time
        Map<String,Object> args = new HashMap<>();
        //args.put("x-max-length",5);
        args.put("x-message-ttl",5000);//This must be of type int
        args.put("x-dead-letter-exchange","dead_direct_exchange");
        args.put("x-dead-letter-routing-key","dead");//fanout does not need to be configured
        return new Queue("ttl.direct.queue",true,false,false,args);}
   
    
    @Bean
    public Binding ttlBingding(){
        return BindingBuilder.bin(directttlQueue()).to(ttldirectExchange()).with("ttlmessage");
    }
}

 

3. Memory disk monitoring

01 RabbitMQ memory warning

02 memory control of rabbitmq

Refer to the help documentation: http://www.rabbbitmq.com/configure.html

When a warning occurs, it can be modified and adjusted through configuration

Command mode

rabbitmqctl set_vm_memory_high_watermark <fraction>
rabbitmqctl set_vm_memory_high_watermark absolute 50MB

fraction/value is the memory threshold. The default is 0.4/2GB, which means that when the memory of RabbitMQ exceeds 40%, a warning will be generated and the connections of all producers will be blocked. The threshold value modified by this command will be invalid after the Broker is restarted. The threshold value set by modifying the configuration file will not disappear with the restart, but it will not take effect until the Broker is restarted like the configuration file is modified  

Configuration file mode: rabbitmq.conf

03 RabbitMQ memory page feed

 

 

04 disk alert for rabbitmq

 

4. Cluster (docker cluster rabbitmq)

1. Create three rabbitmq containers first

docker run -itd --name rabbit01 --hostname myrabbit01 -v /home/software/rabbitmqcluster/rabbitmq01:/var/lib/rabbitmq -e RABBITMQ_DEFAULT_USER=chenjinxian -e RABBITMQ_DEFAULT_PASS=chenjinxian  -e RABBITMQ_ERLANG_COOKIE='rabbitmqCookie' -p 15672:15672 -p  5672:5672 -p 25672:25672 rabbitmq:management

docker run -itd --name rabbit02 --hostname myrabbit02 -v /home/software/rabbitmqcluster/rabbitmq01:/var/lib/rabbitmq -e RABBITMQ_DEFAULT_USER=chenjinxian -e RABBITMQ_DEFAULT_PASS=chenjinxian  -e RABBITMQ_ERLANG_COOKIE='rabbitmqCookie' --link rabbit01:myrabbit01 -p 15673:15672 -p  5673:5672 -p 25673:25672 rabbitmq:management

docker run -itd --name rabbit03 --hostname myrabbit03 -v /home/software/rabbitmqcluster/rabbitmq01:/var/lib/rabbitmq -e RABBITMQ_DEFAULT_USER=chenjinxian -e RABBITMQ_DEFAULT_PASS=chenjinxian  -e RABBITMQ_ERLANG_COOKIE='rabbitmqCookie' --link rabbit01:myrabbit01  --link rabbit02:myrabbit02 -p 15674:15672 -p  5674:5672 -p 25674:25672 rabbitmq:management

After the container is successfully started, readers can access it

  Access through the browser: IP (own IP address): 15672;ip:15673;ip:15674

2. The container node joins the cluster

Execute the following command to enter the first rabbitmq node container:

docker exec -it rabbit01 /bin/bash

After entering the container, operate rabbitmq and execute the following commands:

rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app
exit

Execute the following command to enter the second rabbitmq node container:

docker exec -it rabbit02 /bin/bash

Enter the second rabbitmq node container and execute the following command:

rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@myrabbit01
rabbitmqctl start_app
exit

, enter the third rabbitmq node container and execute the following command:

docker exec -it rabbit03 /bin/bash
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster --ram rabbit@myrabbit01
rabbitmqctl start_app
exit

Finally, you can see the node information

 

Topics: RabbitMQ