This is the 21st day of my participation in the August More Text Challenge

There are two main schemes for RabbitMQ reliability delivery. There are few examples on the web of delayed delivery, double-check, and callback checks. The following is my combination of online information to give their own understanding, if there is a wrong place, please also leave a message pointed out 👼

In the last article, we used scheduled task + message drop and marking to ensure reliable delivery at the production end, which requires two data entries, resulting in performance bottlenecks in high-concurrency scenarios. Therefore, another reliability delivery scheme will be introduced in this article: delayed message delivery, secondary confirmation, callback check, and the implementation process is shown as follows:

  • Process Description:
  1. First the producer enters the business data into the repository and then sends the first message. 🚨 Send messages only after service data is successfully imported into the database.

  2. After the first message is sent, the producer sends another message to the queue with a specified expiration time, such as 5 minutes after the message expires. After the expiration time, the message is rerouted to the dead letter queue. Listener 2 listens on the dead letter queue to obtain the second message.

  3. The consumer listens on the specified queue, queue 1, and receives the message sent for the first time

  4. If the consumer receives the message and completes the consumption, the response is sent back. Instead of a normal return acknowledgement ACK, the consumer sends a Comfirm message to the specified queue, namely queue 2.

  5. Listener 1 listens on queue 2 to get the Confirm returned by the consumer.

  6. When listener 1 receives Comfrim, it saves the message to the MsgDB message database, indicating that the message has been delivered and consumed by the consumer.

  7. 5 minutes after the first message is sent, the second message will be rerouted to the dead letter queue, that is, queue 3, listener 2 listens to queue 3, gets the second message, and then determines whether the message already exists in the database from the message database MsgDB. If no, the previous message is not consumed and the producer needs to be notified to resend the message. If the message exists in the database, it indicates that the message sent for the first time has been successfully consumed by consumers. In this case, no operation is required and the message is successfully delivered.

Demo

TTL+DXL is used to realize delayed delivery.

  1. Declare queues, switches, dead-letter queues, dead-letter switches, and bind them with the routing keys shown above.
@Bean public DirectExchange directExchange(){ return new DirectExchange("direct-Ex",true,false); } @Bean public Queue queue1(){ return new Queue("queue1",true,false,false); } @Bean public Queue queue2(){ return new Queue("queue2",true,false,false); } @Bean public Binding bindQueue1(){ return BindingBuilder.bind(queue1()).to(directExchange()).with("m1"); } @Bean public Binding bindQueue2(){ return BindingBuilder.bind(queue2()).to(directExchange()).with("Lis2"); } @bean public DirectExchange deadLetterExchange(){return new DirectExchange("deadLetterExchange",true,false); } @bean public Queue ttlQueue(){HashMap<String, Object> args = new HashMap<>(); args.put("x-message-ttl",60000); args.put("x-dead-letter-exchange","deadLetterExchange"); args.put("x-dead-letter-routing-key","dead"); return new Queue("ttlQueue",true,false,false,args); } // Bind the TTL queue to the direct-ex switch. The binding key is TTL @bean public binding bindTtlQueue(){return BindingBuilder.bind(ttlQueue()).to(directExchange()).with("ttl"); } @bean public Queue queue3(){return new Queue("queue3",true,false,false); } // Bind queue 3 to the dead-letter switch, Binding key dead @bean public binding bindDeadLetterQueue(){return BindingBuilder.bind(queue3()).to(deadLetterExchange()).with("dead"); }Copy the code
  1. Define listener 1 and listener 2 to listen on queues queue2 and queue3, respectively

  1. Define the consumer, listen to queue 1, and send a Comfirm message to MQ if the message is successfully received and consumed.

4. The Controller receives the request, processes services and sends messages

  1. Postman test

  1. The results

🏁 the above is a brief introduction of another method of reliability delivery on the production side. If there are any mistakes, please leave a comment. If you think this article is helpful to you, please give a thumbs up to 👍