RabbitMQ Summary 2 (MQ Principle Communication Mode Message Response Mechanism)

Table of contents

Composition of MQ

producer

switch

queue

consumer

way of communication

Producer -> Broker (including Exchange)

Exchange -> Binding -> Queue -> Consumer

message reply

Why Introduce Message Reply

Messages are automatically re-enqueued

How to respond to messages

Case Demo


Composition of MQ

Producer consumer switches and queues

producer

The program that generates the data sending message is the producer

switch

The switch is a very important part of RabbitMQ. On the one hand, it receives messages from producers, and on the other hand, it
pushes messages to the queue. The exchange must know exactly what to do with the messages it receives, whether to push them to a specific queue or to multiple queues, or to discard the messages, depending on the type of exchange.

queue

Queues are a data structure used internally by RabbitMQ, and although messages flow through RabbitMQ and applications, they can only be stored
in queues. The queue is constrained only by the host's memory and disk limitations and is essentially a large message buffer. Many producers can send messages to a queue, and many consumers can try to receive data from a queue. This is how we use the queue

consumer

Consuming has a similar meaning to receiving. Most of the time, a consumer is a program waiting to receive messages. Please note that producers, consumers
and message middleware are often not on the same machine. The same application can be both a producer and a consumer.

way of communication

RabbitMQ is a message middleware implemented based on the AMQP protocol. AMQP, similar to the HTTP protocol , is also an application layer protocol, and the network layer uses TCP to communicate. Therefore, RabbitMQ is also a typical CS model, to be precise, it is a CSC model , because with the use of RabbitMQ, there will always be two Clients, Producer and Consumer, and one Broker Server.


To communicate with the Server, the Client must first establish a connection. There are two concepts of Connection and Channel in RabbitMQ. The former is a TCP connection, and the latter is a virtual concept on this connection, which is responsible for logical data transmission. Therefore, in order To save resources, generally create a Connection in a client, and allocate a Channel every time it is used. A Connection can have multiple Channels.

Producer -> Broker (including Exchange)

Broker as a verb in English means to arrange and negotiate, and the noun is a broker. It can be understood as the function of transit distribution.

Exchange -> Binding -> Queue -> Consumer

The exchange
message arrives at the first stop of the broker, matches the routing key in the query table according to the distribution rules, and distributes
the message to the queue. Commonly used types are: direct (point-to-point), topic (publish-subscribe) and fanout
(multicast)

Binding

The virtual connection between the exchange and the queue, the binding can contain the routing key, and the Binding information is saved
in the query table in the exchange, which is used as the distribution basis of the message

Queue

The message is finally sent here to be picked up by the consumer
 

message reply

Why Introduce Message Reply


Consumers may take a while to complete a task, what happens if one of the consumers processes a long task and only completes part of it and suddenly it dies. RabbitMQ marks a message for deletion as soon as it delivers it to a consumer
. In this case, suddenly a consumer hangs up, and we will lose the messages we were processing, as well as subsequent
messages sent to the consumer, because it cannot receive them.
In order to ensure that the message is not lost during the sending process, rabbitmq introduces a message response mechanism. The message response is: after the consumer receives the
message and processes the message, it tells rabbitmq that it has been processed, and rabbitmq can delete the message.

It is also possible to configure automatic acknowledgment of messages, but this mode is only suitable for use when consumers can process these messages efficiently

If something happens when the message is manually answered and the response message is not received, the broker will not delete the message, but will re-enqueue it.

Messages are automatically re-enqueued

If the consumer loses the connection for some reason (its channel is closed, the connection is closed, or the TCP connection is lost) such that the message does
not send an ACK, RabbitMQ will understand that the message was not fully processed and will re-queue it. If other consumers can handle it at this point, it will quickly redistribute it to another consumer. This way, even if a consumer dies occasionally, you can be sure
that no messages will be lost.

How to respond to messages

Case Demo

The message that was originally processed by worker2, because of an exception inside worker2, there was no manual message response, and the broker did not receive the response message, so it re-enqueued the message and redistributed it for processing.


public class Task02 {
    private static final String TASK_QUEUE_NAME = "ack_queue";

    public static void main(String[] argv) throws Exception {
        try (Channel channel = RabbitMqUtils.getChannel()) {

            boolean durable = true;
            channel.queueDeclare(TASK_QUEUE_NAME, durable, false, false, null);
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入信息");
            while (sc.hasNext()) {
                String message = sc.nextLine();
                channel.basicPublish("", TASK_QUEUE_NAME, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes("UTF-8"));
                System.out.println("生产者发出消息" + message);
            }
        }
    }
}

public class Work01 {
    private static final String ACK_QUEUE_NAME="ack_queue";
    public static void main(String[] args) throws Exception {
        Channel channel = RabbitMqUtils.getChannel();
        System.out.println("C1 等待接收消息处理时间较短");
        //消息消费的时候如何处理消息
        DeliverCallback deliverCallback=(consumerTag, delivery)->{
            String message= new String(delivery.getBody());
            SleepUtils.sleep(1);
            System.out.println("接收到消息:"+message);
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
        };
        //采用手动应答
        boolean autoAck=false;
        channel.basicConsume(ACK_QUEUE_NAME,autoAck,deliverCallback,(consumerTag)->{
            System.out.println(consumerTag+"消费者取消消费接口回调逻辑");
        });
    }
}

public class Work02 {
    private static final String ACK_QUEUE_NAME = "ack_queue";

    public static void main(String[] args) throws Exception {
        Channel channel = RabbitMqUtils.getChannel();
        //消息消费的时候如何处理消息
        DeliverCallback deliverCallback = (consumerTag, delivery) -> {
            String message = new String(delivery.getBody());
            System.out.println(" 出错了,消息没有应答,此时消息会重新入队交给 其他worker处理");
            int i = 1/0;
            System.out.println("接收到消息:" + message);
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
        };
        //采用手动应答
        boolean autoAck = false;
        channel.basicConsume(ACK_QUEUE_NAME, autoAck, deliverCallback, (consumerTag) -> {
            System.out.println(consumerTag + "消费者取消消费接口回调逻辑");
        });
    }
}

Guess you like

Origin blog.csdn.net/weixin_40757930/article/details/128610092