Concept and usage of message queue Rabbit MQ

Posted by monotoko on Wed, 20 Oct 2021 06:07:53 +0200

The popular open source message middleware in the industry includes ActiveMQ, rabbitmq, RocketMQ, Kafka and ZeroMQ, among which rabbitmq, RocketMQ and Kafka are the most widely used. Redis can also be a mechanism similar to Queue and Pub/Sub to some extent, but it is not strictly a message oriented middleware. This article will talk about the basic concept and use of rabbitmq

What is a message queue

What is a Message: it refers to the data transmitted between applications. Messages can be very simple, such as containing only text strings, or they can be more complex and may contain embedded objects.
What is Message Queue: it is a communication mode between applications. Messages can be returned immediately after being sent. The message system ensures the reliable delivery of messages. The queue is divided into two ends, sender and consumer. The message sender only needs to put the message into the queue, regardless of who consumes it. The consumer consumes the message, regardless of who put the message in the queue. Asynchronous cooperative processing can be realized

RabbitMq usage scenario

Taking the mall order system as an example, we need to generate orders, reduce inventory, deduct balance, send text messages, generate documents and notify merchants after placing orders. If the order quantity is small, it can be completed together, but when the order quantity increases, so many contents can be operated at one time, resulting in slow system, poor experience and great pressure on the single node server. At this time, we need to split the operations that do not need to be processed immediately and notify the merchant through MQ (send SMS). Send a message to MQ after placing an order. The split operation will be processed after receiving the message. It is mostly used for peak staggering processing, maintaining final consistency and broadcasting.

RabbitMQ advantages and disadvantages

advantage:

  1. Lightweight, fast deployment and easy use
  2. Support flexible routing configuration. In RabbitMQ, there is a switch module between the producer and the queue. According to the configured routing rules, messages sent by producers can be sent to different queues. The routing rules are flexible and can be implemented by yourself.
  3. RabbitMQ's client supports most programming languages.

Disadvantages:

  1. If a large number of messages pile up in the queue, performance will decline sharply
  2. RabbitMQ has the worst performance in Kafka and RocketMQ, processing tens of thousands to hundreds of thousands of messages per second. If the application requires high performance, do not select RabbitMQ.
  3. RabbitMQ is developed by Erlang, and the cost of function expansion and secondary development is very high.

RabbitMQ features

RabbitMQ is an open source implementation of AMQP developed by Erlang language.
AMQP: Advanced Message Queue Protocol. It is an open standard of application layer protocol. It is designed for message oriented middleware. The client and message oriented middleware based on this protocol can transmit messages without being limited by products, development languages and other conditions.
RabbitMQ originated from the financial system and is used to store and forward messages in distributed systems. It performs well in ease of use, scalability and high availability. Specific features include:
Reliability
RabbitMQ uses some mechanisms to ensure reliability, such as persistence, transmission confirmation and release confirmation.
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.
Message Clustering
Multiple RabbitMQ servers can form a cluster to form a logical Broker.
Highly Available Queues
The queue can be mirrored on the machines in the cluster, so that the queue is still available in case of problems with some nodes.
Multi protocol
RabbitMQ supports a variety of message queuing protocols, such as STOMP, MQTT, and so on.
Many Clients
RabbitMQ supports almost all common languages, such as Java,. NET, Ruby, and so on.
Management interface (Management UI)
RabbitMQ provides an easy-to-use user interface that allows users to monitor and manage many aspects of message Broker.
Tracking mechanism
If the message is abnormal, RabbitMQ provides a message tracking mechanism so that the user can find out what happened.
Plug in system
RabbitMQ provides many plug-ins to extend from many aspects, or you can write your own plug-ins.

RabbitMQ logical model and basic concepts

Message model

All MQ products are the same process in terms of model abstraction:
Consumers subscribe to a queue. The producer creates a message, then publishes it to the queue, and finally sends the message to the listening consumer.

RabbitMQ basic concepts

  • Message
    Message, which is unnamed, consists of a message header and a message body. The message body is opaque, while the message header consists of a series of optional attributes, including routing key, priority (priority relative to other messages), delivery mode (indicating that the message may need persistent storage), etc.
  • Publisher
    The producer of messages is also a client application that publishes messages to the switch.
  • Exchange
    The switch is used to receive the messages sent by the producer and route these messages to the queue in the server.
  • Binding
    Binding for the association between message queues and switches. A binding is a routing rule that connects the switch and message queue based on the routing key, so the switch can be understood as a routing table composed of binding.
  • Queue
    Message queue, which is used to save messages until they are sent to consumers. It is the container of messages and the destination of messages. A message can be put into one or more queues. The message is always in the queue, waiting for the consumer to connect to the queue and take it away.
  • Connection
    A network connection, such as a TCP connection.
  • Channel
    Channel, an independent bidirectional data flow channel in a multiplexed connection. The channel is a virtual connection established in the real TCP connection. AMQP commands are sent through the channel. Whether publishing messages, subscribing to queues or receiving messages, these actions are completed through the channel. Because it is very expensive to establish and destroy TCP for the operating system, the concept of channel is introduced to reuse a TCP connection.
  • Consumer
    The consumer of a message, representing a client application that gets a message from a message queue.
  • Virtual Host
    A virtual host that represents a batch of switches, message queues, and related objects. A virtual host is a separate server domain that shares the same authentication and encryption environment. Each vhost is essentially a mini RabbitMQ server with its own queue, switch, binding and permission mechanism. vhost is the basis of AMQP concept and must be specified during connection. The default vhost of RabbitMQ is /.
  • Broker
    Represents a message queuing server entity.

Exchange type

Exchange distributes messages according to different types. At present, there are three types: direct, fanout and topic.

direct

::: hljs-center

:::
If the routing key in the message is consistent with the binding key in Binding, the switch will send the message to the corresponding queue. The routing key exactly matches the queue name. If a queue is bound to the switch and requires the routing key to be "dog", only the messages marked with the routing key "dog" will be forwarded, and neither "dog. Supply" nor "dog.guard" will be forwarded. It is an exact match, unicast mode.

fanout

::: hljs-center

:::
Every message sent to the fan out type switch will be distributed to all bound queues. The fanout switch does not handle routing keys, but simply binds queues to the switch. Each message sent to the switch will be forwarded to all queues bound to the switch. Much like subnet broadcasting, hosts in each subnet get a copy of the message. The fan out type is the fastest to forward messages.

topic

::: hljs-center

:::
The topic switch allocates the routing key attribute of the message through pattern matching to match the routing key with a pattern. At this time, the queue needs to be bound to a pattern. It cuts the strings of routing and binding keys into words separated by dots. It also recognizes two wildcards: the symbol "#" and the symbol ""# Match 0 or more words, no more than one word.

Java+RabbitMq basic usage

RabbitMQ supports multiple languages. Let's take JAVA language as an example
1.maven add dependency

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

2. Message producer

 /**
     * producer
     */
    @Test
    public void producer(){
        try{
            //Create connection factory
            ConnectionFactory factory = new ConnectionFactory();
            factory.setUsername("**");
            factory.setPassword("**");
            //Set RabbitMQ address
            factory.setHost("*******");
            factory.setVirtualHost("yzs-dev");
            //Establish a connection to the proxy server
            Connection conn = factory.newConnection();
            //Access channel
            Channel channel = conn.createChannel();
            //Declaration switch
            String exchangeName = "DLXX";
            channel.exchangeDeclare(exchangeName, "direct", true);
            String routingKey = "routingKey";
            //Release news
            byte[] messageBodyBytes = "quit".getBytes();
            channel.basicPublish(exchangeName, routingKey, null, messageBodyBytes);
            channel.close();
            conn.close();
        }catch (Exception e){
            System.out.println("Production message error:" + e);
        }
    }

3. Message consumers

/**
     * Consumer
     */
    @Test
    public void consumer(){
        try{
            ConnectionFactory factory = new ConnectionFactory();
            factory.setUsername("***");
            factory.setPassword("**");
            factory.setHost("*****");
            factory.setVirtualHost("yzs-dev");
            //Establish a connection to the proxy server
            Connection conn = factory.newConnection();
            //Access channel
            final Channel channel = conn.createChannel();
            //Declaration switch
            String exchangeName = "DLXX";
            channel.exchangeDeclare(exchangeName, "direct", true);
            //Declaration queue
            String queueName = "queue-name";
            String routingKey = "routingKey";
            //Bind the queue, and bind the queue and the switch through the key hola
            channel.queueBind(queueName, exchangeName, routingKey);
            //Consumption news
            boolean autoAck = false;
            String consumerTag = "";
            channel.basicConsume(queueName, autoAck, consumerTag, new DefaultConsumer(channel) {
                @Override
                public void handleDelivery(String consumerTag,
                                           Envelope envelope,
                                           AMQP.BasicProperties properties,
                                           byte[] body) throws IOException {
                    String routingKey = envelope.getRoutingKey();
                    String contentType = properties.getContentType();
                    System.out.println("Consumed routing keys:" + routingKey);
                    System.out.println("Type of content consumed:" + contentType);
                    long deliveryTag = envelope.getDeliveryTag();
                    //confirmation message
                    channel.basicAck(deliveryTag, false);
                    System.out.println("Consumed message body content:");
                    String bodyStr = new String(body, "UTF-8");
                    System.out.println(bodyStr);

                }
            });
        }catch (Exception e){
            System.out.println("Consumption message error:" + e);
        }
    }

Operation results:

Java+Spring Boot+RabbitMq basic usage

1.maven import dependency
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
    <version>2.5.5</version>
</dependency>
2. Add configuration
spring:
  rabbitmq:
    host: *******
    port: 5672
    username: **
    password: **
    virtualHost: yzs-dev
3. Producers
 /**
     * producer
     */
    @Test
    public void producer(){
        rabbitTemplate.convertAndSend("DLXX","lsy-test-topic.lsy-test-queue","12345");
    }
4. Consumers
@Slf4j
@Component
public class Consumer {

    @RabbitListener(queues="lsy-test-topic.lsy-test-queue.dlq")
    public void consumer(Message message, Channel channel){
        String msg=new String(message.getBody());
        log.error(JSON.toJSONString(msg));
    }

}

epilogue

The full text is long. Thank you for your patience.
Through simple use, we understand the simple principle and basic usage of rabbitmq. spring boot has done a lot of things silently. Make configuration and use relatively simple.

Topics: Java RabbitMQ Spring Boot Middleware message queue