RabbitMq producers and consumers? (3)

preface

The basic use of rabbitMq and the four switch types have been explained, is that all rabbitMq is about? Of course not. Here are some guesses and questions I’ve encountered while learning RabbitMq.

Switch queue relationship

  • The following example only illustrates the case of a successful route to a queue, not an unsuccessful route
  1. In order for a queue to receive a message, it must bind the corresponding switch and send the message to the bound switch so that the queue can listen for the message, except for the default switch.
  2. When a message is sent to a switch, the switch sends a message to the bound queues at the same time. That is, one switch corresponds to n queues. One switch sends a message to n bound queues, that is, a total of N messages are received.
  3. Serving T nodes does not cause the switch to send duplicate messages, that is, t* N messages are not generated and will only be consumed by one node.

How can producers and consumers ensure that messages are sent and received successfully?

Channel

Why do I take out Channel separately? Channels are very important in RabbitMq!

  1. How is a Channel created?

Here are the basics: Many services require multiple reliable long connections to the middleware, such as TCP, but it is not advisable for an application to open multiple TCP connections to the middleware because it consumes system resources and the server firewall is difficult to maintain, so RabbitMq provides the concept of a Channel. In the case of sharing a TCP connection, resource multiplexing is separated by channels, which is equivalent to resource isolation. Data between channels does not communicate with each other and is not affected. In addition, a Channel exists only when there is a TCP connection, but does not exist alone. That is to say, a Channel will be closed when the service is closed and the connection is disconnected. 2. So when is a Channel generated? Is there a problem with too many channels? The following author quotes the official words. Each channel consumes a relatively small amount of memory on the client. Depending on the implementation details of the client library, it can also use a dedicated thread pool (or similar) to schedule consumer operations, so one or more threads (or similar). So the official has said that the small memory is relatively small, so the author as mang fu, certainly not him! So how did Channel come about? The number of channels to be created is determined by the number of consumers listening to them, which leads to resource isolation for a Channel

    @RabbitListener(queuesToDeclare = {@Queue(name = "Headers_ALL_QUEUE", arguments = {@Argument(name = "all-1", value = "value1"), @Argument(name = "all-2", value = "value2")})})
    public void handlerAll1(Message message) {
        log.info("[Headers_ALL_QUEUE1]:{}".new String(message.getBody(), StandardCharsets.UTF_8));
    }

    @RabbitListener(queuesToDeclare = {@Queue(name = "Headers_ALL_QUEUE1", arguments = {@Argument(name = "all-1", value = "value1"), @Argument(name = "all-2", value = "value2")})})
    public void handlerAll2(Message message) {
        log.info("[Headers_ALL_QUEUE2]:{}".new String(message.getBody(), StandardCharsets.UTF_8));
    }

    @RabbitListener(queues = {"FANOUT_QUEUE"})
    public void handlerH(Message message, Channel channel) {
        System.out.println(channel);
        log.info("[Message coming]:{}".new String(message.getBody(), StandardCharsets.UTF_8));
    }
Copy the code

Start the service when there are three consumersSo how do we control the number of channels created?

The starter of RabbitMQ can be set directly
spring.rabbitmq.requested-channel-max=2
Copy the code

So what happens if we have 3 consumers set to 2?No doubt that’s a mistake!

Consumer message confirmation mechanism

  • RabbitMq specifies a protocol based on the above questions. How does RabbitMq remove messages from queues to avoid re-consumption according to AMQP 0-9-1? When consumers receive and process messages, the nodes may crash during receiving or processing, or the network is out of order, and messages cannot be consumed normally.
  • RabbitMq does two things based on the above questions
  1. The agent sends messages to the application (using either basic.deliver or basic. get-OK methods).
  2. After the application sends back confirmation (using the basic.ack method).
  • When a message is sent to a node’s application, rabbitMq allows the node to respond to it in one of three ways
  1. Basic. ack is used for acknowledgment
  2. Basic. nack is used for negative validation (this is only available with AMPQ 0-9-1 protocol)
  3. Basic. reject is used to deny confirmation, but there are some differences with nack
  • RabbitMq receives ACK or reject and removes the message from the queue, confirming that the message has been consumed, whereas the application does not consume the message with reject
  • And what does basic.nack do? RabbitMq allows Nacks to batch acknowledge messages, reducing network traffic and interactions.
/ * * *@author Kakki
 * @version 1.0
 * @createThe 2021-06-18 "* /
@Component
@Slf4j
public class MqCustomer {

    @RabbitListener(queues = {"FANOUT_QUEUE"})
    public void handlerH(Message message, Channel channel) {
        channel.basicAck(Long deliverTag, boolean multiple);
        log.info("[Message coming]:{}".newString(message.getBody(), StandardCharsets.UTF_8)); }}Copy the code
  • If multiple is true, nACK will be used. If you do not know deliverTag, false will be used, while reject does not have this field.
  • DeliverTag actually means that when MQ prefetches messages, ACK is confirmed one message at a time, while NACK can confirm in batches. When deliverTag is set to 9, it will confirm all unconfirmed messages before 9, which is also the batch confirmation of NACK

Producer message sending acknowledgement mechanism

  • How can producer messages be correctly kept from being lost, that is, to be able to reach MQ, and there are two ways in which rabbitMq’s AMQP 0-9-1 protocol can be used to keep messages from being lost
  1. Make channels transactional and then publish and commit for each message or group of messages. In this case, the transaction is unnecessarily heavy and reduces throughput by a factor of 250.
  2. Using transaction throughput can be reduced by 250 times and the performance is not good, so a confirmation mechanism is introduced, which is modeled on the principle of consumer confirmation mechanism
  • Producer confirmation is enabled for RabbitMq by default

  • So how do you turn on transaction mode?

Is simple to see the source code to know, did not elaborate, here you can see the com. The rabbitmq. Client. Channel. ConfirmSelect () method

summary

This article has only covered how producers and consumers can either acknowledge the message sent or receive it. Of course, I don’t think automatic confirmation can be used in all business scenarios, so you should choose your own confirmation mechanism according to the business scenario.