confirm of rabbit-producer and ack mode of consumer

Keywords: Java Spring Mobile Programming network

This article shares with you some practical operations about rabbit production and consumer; just like the title of the article, the main contents are confirm of producer and ack of consumer, both of which are used to ensure data integrity and prevent data loss.

  • confirm mode of producer
  • ack mode of consumer

confirm mode of producer

Firstly, there is such a business scenario: 1:a system needs to send an activity content short message to the user's mobile phone before doing the activity. Because the number of users is a little large, it can make the short message service consume the short message by inserting data into the short message mq.

In order to ensure that all users receive messages and that the insertion is completed in a short time (so asynchronous insertion is used (fast), we need to know whether each insertion of mq is successful or not. If it is not successful, we can collect the failed information and then reissue it (so confirm mode comes in handy). Figure design:

In spring boot, you can use the factory class based on amqp encapsulation to open confirm mode, and then set the callback function through the Rabbit Template template, as follows:

 1     ///region producer production - confirm Pattern
 2 
 3     public RabbitTemplate getRabbitTemplate(RabbitTemplate.ConfirmCallback confirmCallback) {
 4         return this.getRabbitTemplate(this.connectionFactory(), confirmCallback);
 5     }
 6 
 7     public RabbitTemplate getRabbitTemplate(CachingConnectionFactory connectionFactory, RabbitTemplate.ConfirmCallback confirmCallback) {
 8         RabbitTemplate template = new RabbitTemplate(connectionFactory);
 9         //product open confirm Pattern
10         connectionFactory.setPublisherConfirms(true);
11         //Set up confirm Callback processing
12         template.setConfirmCallback(confirmCallback);
13         return template;
14     }
15     ///endregion

Here we pass our custom callback method through RabbitTemplate.ConfirmCallback function programming. We collect the result information returned by confirm as follows:

1         RabbitUtil rabbitUtil = new RabbitUtil(this.getFirstNode().getLink());
2         RabbitTemplate template = rabbitUtil.getRabbitTemplate((a, b, c) -> {
3             System.out.println("firstNodeTpl - ConfirmCallback Of Id: " + a.getId() + ";Status:" + b + ";Information:" + c);
4         });

Finally, we can send mq information through the convertAndSend method of RabbitTemplate instance. We can see the following recorded information in the log:

The status here is true: to indicate that send succeeded, false: to indicate that send failed; usually when false, information c will have an error prompt in response. Here the network is disconnected, as follows:

ack mode of consumer

Secondly, there is a scenario 2: if the service invoker sends an abnormal short message interface (short message operator interface arrears), when the short message service consumes the mq queue information, we fail to send and the user can not receive the short message, but the mq message has been consumed by default (default open ack). There is no record in rabbit (kafka exception); if you want mq messages to exist when business logic is abnormal, you can use ACK mode.

In spring boot, we can use the factory class encapsulated by amqp to turn off the automatic ack mode and change it to manual ACK mode. Only when the business code process is finished, the rabbit message can be discarded by setting ack identifier through the code. If manual mode is set and ACK identifier is not submitted, then the message in mq can be discarded. There has always been an unrelease (rabbit repeats the noack message into the queue after each consumer consumption):

 1     ///region consumer Monitor - Manual ack
 2     public SimpleRabbitListenerContainerFactory listenerContainerFactory() {
 3         return this.listenerContainerFactory(this.connectionFactory());
 4     }
 5 
 6     public SimpleRabbitListenerContainerFactory listenerContainerFactory(ConnectionFactory connectionFactory) {
 7         SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
 8         factory.setConnectionFactory(connectionFactory);
 9         //Code manual ack
10         factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
11         //Open up the number of consumers
12         factory.setConcurrentConsumers(2);
13         //Accept data volume per time, default 250
14         factory.setPrefetchCount(300);
15         return factory;
16     }
17     ///endregion

The manual ack mode is set up through the connection factory, then the mq message is obtained, the normal business logic is completed, and finally the ACK is manually notified to release the message, as follows:

1     @RabbitListener(containerFactory = "firstNodeListener", queues = {"${shenniu.rabbits.firstNode.queue}"})
2     private void firstNodeListener(String msg, Channel channel, Message message) {
3         try {
4             long deliverTag = message.getMessageProperties().getDeliveryTag();
5             System.out.println("firstNodeListener - Consumer news [" + deliverTag + "] - " + msg);
6             channel.basicAck(deliverTag, true);
7         } catch (Exception ex) {
8         }
9     }

Here ack is notified mainly according to the unique number of mq message (delivery Tag); if we do not set ACK confirmation, the message status will be as follows: rabbit management background:

Posted by gavinbsocom on Fri, 30 Aug 2019 05:41:37 -0700