springBoot uses redis to make rabbitMQ idempotent to prevent repeated consumption

Hello everyone, today I will share my method of using redis to prevent repeated consumption of MQ.
Whenever MQ is used, there will be two big confusions.

One is to ensure that the message is not lost (message is highly available) and the
other is to prevent repeated consumption of messages.

To ensure that the message is not lost, we can use MQ's callback to ensure whether the message is sent successfully and whether it is sent to the exchange and queue.
But for the repeated consumption of messages, I checked a lot of information on the Internet and found roughly the following two points:
First, use the primary key of the database (the primary key cannot be repeated when inserting)
Second, use the set operation of redis (set the same key will Direct coverage)

The above two points can indeed solve the repeated consumption of messages, but only apply to consumers who only do insert operations, and my consumers call other people’s interfaces, and other people’s interfaces are inserted (the data I pass is not his Primary key, so the first point above obviously cannot be used). If I use the first point above, the data on my side will not be repeated, but the data on the other side’s interface will be repetitive.
Then I thought of the setNT method of redis.
**setNT:** When the specified key does not exist, set the specified value for the key. The setting is successful, and 1 is returned. The setting fails, and 0 is returned.
The redisTemplate in springboot returns true and false, that is, true for success and false for failure.
In fact, the messageId of the message can be stored in redis as a key to determine whether the message is consumed. So there is the following code.

   return  (boolean)redisTemplate.execute((RedisCallback) action->{
    
    
            return action.setNX(messageID.getBytes(),messageID.getBytes());
        });

If the ID exists, fasle is returned, then the business logic is not executed, and if it does not exist, the ID is stored as a key in redis, and true is returned.
This perfectly solves the problem of repeated consumption of rabbitMQ

Precautions

  1. Because the key set by setNT has no cache time, that is, it will never expire, so after the business is executed, an expiration time should be set to avoid occupying resources
  2. If the manual ACK mode is set by MQ, an error is reported or the TTL is out of date, then the key needs to be deleted in the dead letter queue.

Guess you like

Origin blog.csdn.net/ChenLong_0317/article/details/106767231