Message loss
The message was sent out and did not reach the message server due to network reasons
- Try catch, sending messages may lead to network failure. After the failure, there should be a retry mechanism, which can be recorded in the database, and the method of regular scanning and retransmission should be adopted
- Log whether each message status is received by the server or not
- Do a good job of regular retransmission. If the message is not sent successfully, regularly go to the database to scan the messages that are not sent successfully for retransmission
When the message arrives at the Broker, the Broker needs to write the message to disk (persistence) before it is successful. At this time, the Broker has not been successfully down for persistence
- publisher must also add a confirmation callback mechanism to confirm successful messages and modify the database message status
In the state of automatic ACK. Consumers received the news, but they didn't have time to consume and then went down
- The manual ACK must be enabled, and it can be removed only after the consumption is successful, or it fails or does not have time to process the noAck and rejoin the team
# Enable the confirmation of the sender message arrival service (Broker) spring.rabbitmq.publisher-confirm-type=correlated # Enable the confirmation of the sender's message arrival Queue spring.rabbitmq.publisher-returns=true # As long as the message arrives at the queue, the priority callback returnConfirm is sent asynchronously spring.rabbitmq.template.mandatory=true # Enable manual ack mechanism spring.rabbitmq.listener.direct.acknowledge-mode=manual
package com.ww.ideaapp.order.config; import org.springframework.amqp.core.*; import org.springframework.amqp.rabbit.connection.CorrelationData; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; import org.springframework.amqp.support.converter.MessageConverter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.lang.Nullable; import javax.annotation.PostConstruct; @Configuration public class RabbitMQConfig { @Autowired RabbitTemplate rabbitTemplate; /** * Message transformation using JSON serialization mechanism * * @return */ @Bean public MessageConverter messageConverter() { return new Jackson2JsonMessageConverter(); } /** * Customize RabbitTemplate * 1,The service (Broker) received a message callback * 1)spring.rabbitmq.publisher-confirm-type=correlated * 2)Set ConfirmCallback * 2,The message correctly arrives at the Queue callback * 1)spring.rabbitmq.publisher-returns=true * spring.rabbitmq.template.mandatory=true * 2)Set ReturnCallback * 3,Consumer confirmation (automatic confirmation by default) * Set manual sign in. If there is no ack, the message will always be in the unacketed state. Even if the consumer goes down, the message will not be lost, it will change to Ready again, and it will be sent again next time * spring.rabbitmq.listener.direct.acknowledge-mode=manual * channel.basicAck(deliveryTag, false) Sign for * channel.basicNack(deliveryTag, false, false) deny sb. a visa * long deliveryTag: channel Internal self increasing */ @PostConstruct // When the constructor creation object (RabbitConfig) is completed, this method is called. public void initRabbitTemplate() { // Set message arrival service (Broker) callback rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() { /** * Confirmation callback mechanism * * @param correlationData Unique associated data of the current message (message unique ID) * @param b Whether the message was received successfully * @param s Failure reason */ @Override public void confirm(@Nullable CorrelationData correlationData, boolean b, @Nullable String s) { System.out.println("ConfirmCallback==>correlationData["+correlationData+"]==>b["+b+"]==>s["+s+"]"); } }); // Set message arrival Queue acknowledgement callback rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() { /** * As long as the message is not delivered successfully, the failed callback will be triggered * * @param message Post failed message details * @param i Failure status code replied by the server * @param s Text content replied by the server * @param s1 Which switch is this message sent to * @param s2 The routing key used for this message at that time */ @Override public void returnedMessage(Message message, int i, String s, String s1, String s2) { System.out.println("fail message==>message["+message+"]==>i["+i+"]==>s1["+s1+"]==>s2["+s2+"]"); } }); } }
Duplicate message
The message consumption is successful, the transaction has been committed, and the ACK goes down, resulting in no ack success. The Broker's message changes from unack to ready and is sent to other consumers
- The consumer business interface should be designed to be idempotent. For example, inventory deduction has the status flag of the work order
- Each message sent using the anti duplication table (mysql/redis) has a unique business ID, and it will not be processed after processing
- Each message of rabbitMQ has a redelivered field, which can obtain whether it has been redelivered rather than delivered for the first time
Message consumption failed. Due to the retry mechanism, the message is automatically sent out again
Message backlog
Consumer downtime backlog
Insufficient consumer capacity and backlog
The sender sends too much traffic
- Online more consumers for normal consumption
- On line special queue message service, Jiang primary school takes it out in batches, records the database, and processes it slowly offline