Personal business card:
Blogger: Drunkardᝰ.
Personal profile: Indulge in wine, and use the energy of wine to fight for a future.
This article is inspirational: When three of us travel together, we must be my teacher.
This project is based on Java "SpringCloud Microservice Technology Stack" by the dark horse programmer of station B , SpringCloud+RabbitMQ+Docker+Redis+search+distributed
[SpringCloud+RabbitMQ+Docker+Redis+search+distributed, detailed system explanation springcloud microservices technology stack course | Dark horse programmer Java microservices] Click to watch
Table of contents
2. Message Reliability
3. Consumer message confirmation
RabbitMQ is a burn-after-read mechanism. RabbitMQ will delete the message immediately after confirming that it has been consumed by the consumer.
RabbitMQ uses consumer receipts to confirm whether the consumer has successfully processed the message: after the consumer obtains the message, it should send an ACK receipt to RabbitMQ to indicate that it has processed the message.
Imagine this scenario:
- 1) RabbitMQ delivers messages to consumers
- 2) After the consumer obtains the message, it returns ACK to RabbitMQ
- 3) RabbitMQ deletes messages
- 4) The consumer is down and the message has not been processed yet
In this way, the message is lost. Therefore, the timing of the consumer returning ACK is very important.
SpringAMQP allows configuration of three confirmation modes:
Manual: Manual ack, you need to call the API to send ack after the business code is completed.
auto: automatic ack. Spring monitors the listener code for exceptions. If there is no exception, ack is returned; if an exception is thrown, nack is returned.
none: Turn off ack. MQ assumes that the consumer will successfully process the message after getting it, so the message will be deleted immediately after delivery.
It can be seen from this:
- In none mode, message delivery is unreliable and may be lost.
- The auto mode is similar to the transaction mechanism. When an exception occurs, nack is returned and the message is rolled back to mq; if there is no exception, ack is returned.
- Manual: You can judge when to ack based on the business situation.
Generally, we just use the default auto.
- Demo none mode
Modify consumer
the mq address, user name, password and other configurations in the service's application.yml file, and add the following content:
spring:
rabbitmq:
listener:
simple:
acknowledge-mode: none
Modify the method in the SpringRabbitListener class of the consumer service to simulate a message processing exception:
@RabbitListener(queues = "simple.queue")
public void listenSimpleQueue(String msg) {
log.info("消费者接收到simple.queue的消息:{}", msg);
System.out.println(1/0);
log.debug("消息处理完成!");
}
test:
@Test
public void testSimple() {
rabbitTemplate.convertAndSend("simple.queue", "hello, money");
}
The test can find that when the message processing throws an exception, the message is deleted by RabbitMQ before it is read by the consumer.
- Demo auto mode
Change the confirmation mechanism to auto:
spring:
rabbitmq:
listener:
simple:
acknowledge-mode: auto
Add a listening class, listen to the queue, and throw exceptions.
@RabbitListener(queues = "simple.queue")
public void listenSimpleQueue(String msg) {
System.out.println("消费者接收到simple.queue的消息:{" + msg + "}");
throw new RuntimeException();
}
When starting the consumer project, the console repeatedly reports errors.
Break the point at the abnormal position and send the message again. When the program is stuck at the breakpoint, you can find that the message status is unack (undetermined status):
After the exception is thrown, because Spring will automatically return nack, the message returns to the Ready state and is not deleted by RabbitMQ: