RabbitMQ message reliability guarantee


There is actually no implementation of message delay in RabbitMQ, but we can implement message delay through TTL and dead letter routing.

1. Producer Guarantee

1. Failure notification

When the producer sends a message to the broker, it must ensure the reliability of the message. There are two main solutions:

  • failure notification
  • sender acknowledgment

1. Failure notification: If a message cannot be delivered to the queue, a failure notification will appear. You can start the failure notification. In native programming, set the mandatory flag when sending the message to turn on the fault detection mode
Insert image description here
. 2. Implementation method:
Configuration in spring :

pring:
  rabbitmq:
    # 消息在未被队列收到的情况下返回
    publisher-returns: true

In java code, the sender needs to implement the ReturnCallback interface to implement failure notification:

public class sendToMessage implements RabbitTemplate.ReturnCallback {
    
    
    
    @Override
    public void returnedMessage(Message message, int i, String s, String s1, String s2) {
    
    
        
    }

    @Override
    public void returnedMessage(ReturnedMessage returned) {
    
    
        RabbitTemplate.ReturnCallback.super.returnedMessage(returned);
    }
}

3. Problems encountered: If the message is correctly routed to the queue, the publisher will not receive any notification. The problem is that it cannot ensure that the message is published successfully, because the message routed to the queue may be lost.

2. Confirmation by sender

Sender confirmation means that after the producer delivers the message, if the Broker receives the message, it will give the producer a response, and the producer will receive the response to confirm whether the message is sent to the Broker normally. This method also makes the message reliable. Core guarantee of sexual delivery

  • Messages are routed to the queue via the exchange exchange
  • Send the message to the broker, that is, to the exchange switch

Note: The failure to send confirmation will only occur if there is an internal error in RabbitMQ that cannot be delivered.

1 Unroutable: After the current message reaches the exchange, it is confirmed by the sender that it is successful.
Insert image description here
First, when the RabbitMQ exchange is not routable, the message will not be delivered to the queue at all, so here we only care about the path to the exchange. When the message is successfully delivered After the switch, the confirmation operation will be performed

In addition, during this process, after the producer receives the confirmation message, because the message cannot be routed, the message is also invalid and cannot be delivered to the queue. Therefore, under normal circumstances, it will be used in conjunction with the failure notification, which is generally set here. Mandatory mode, if failure occurs, the addReturnListener listener will be called for processing.

2. Can be routed; as long as the message can reach the queue, it can be confirmed. Generally,
Insert image description here
messages that fail to be routed will appear when an internal error occurs in RabbitMQ. After the message is delivered to all matching queues, the broker will send a confirmation to the producer. (Containing the unique ID of the message), this allows the producer to know that the message has correctly arrived at the destination queue.

If the message and queue are durable, the confirmation message will be sent after the message is written to disk. The delivery-tag field in the confirmation message sent back to the producer by the broker contains the sequence number of the confirmation message.

3. Implementation method

Configuration in spring:

spring:
  rabbitmq:    
    # 开启消息确认机制
    publisher-confirm-type: correlated

In the java code, the sender needs to implement the ConfirmCallback interface to realize the failure notification

public class sendToMessage implements RabbitTemplate.ConfirmCallback {
    
    


    @Override
    public void confirm(CorrelationData correlationData, boolean b, String s) {
    
    
        
    }
}

3. Broker loses message

Turn on the persistence of RabbitMQ, that is, after the message is written, it will be persisted to the disk. Even if mq hangs up at this time, the previously stored data will be automatically read after restarting.

1. Persistence queue

@Bean
public Queue queue(){
    
    
    return new Queue(queueName,true);
}

2. Persistent exchanger

@Bean
DirectExchange directExchange() {
    
    
    return new DirectExchange(exchangeName,true,false);
}

3.Send persistent messages

When sending a message, set the deliveryMode=2 of the message

Note: If you use SpringBoot, deliveryMode=2 is automatically set when sending a message, and there is no need to set it manually.

2. Consumer message reliability (consumer manual confirmation)

1. RabbitMQ defaults to automatic ack, which needs to be modified to manual ack, that is, after your own program determines that the message has been processed, you can manually submit the ack. At this time, if you encounter a situation where the process hangs without processing the message, due to Without submitting the ack, RabbitMQ will not delete the message, but will send the message to other consumers for processing, but the message will not be lost.

2. spring configuration file

spring:
  rabbitmq:
    listener:
      simple:
        acknowledge-mode: manual  # 手动ack

3. Parameter introduction

acknowledgment-mode: manual means to enable manual ack, and the other two values ​​of this configuration item are none and auto

  • auto: Consumers decide whether to submit ack or nack according to whether the program executes normally or throws an exception. Do not confuse none with auto
  • manual: manual ack, the user must submit ack or nack manually
  • none: no ack mechanism

4. Consumer realization

public class sendToMessage {
    
    

    @RabbitHandler
    public void processOrder(Message massage, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws IOException {
    
    
        channel.basicAck(tag, false);
    }
    
}

3. Business reliability analysis

Insert image description here
1. Message loss: In this business scenario, the user initiates a taxi request. If the user message is lost, there will be no impact on the overall business. The user can initiate the taxi operation again. The probability of this message loss problem is very low, and a simplified design can be carried out. , if there is a sending failure, you only need to roll back the operation in redis.

2. Idempotence verification: Because of the use of delay queue, there is no need for idempotence verification for this business, because if the key of redis user ranking exists at the first timeout, it will be deleted. Next A value that redis does not have is deleted once. This operation is idempotent, so there is no need to consider idempotence

3. Data rollback: Although there is no need to ensure that the message is not lost at all and the message is idempotent, it needs to be considered that if a problem occurs, the key value inserted into Redis needs to be rolled back to prevent it from affecting the normal business judgment.

Guess you like

Origin blog.csdn.net/weixin_44702984/article/details/131634539