rabbitmq配合redis防止重复消费

package com.lezu.springboot.test;

import com.lezu.springboot.configuration.config.rabbitmq.DirectExchangeConfig;
import org.junit.jupiter.api.Test;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author lianJiaYu
 * @date 2022/6/21 18:33
 */
@SpringBootTest
public class LianTest {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Test
    public void producer() {
        MessagePostProcessor messagePostProcessor = message -> {
            MessageProperties messageProperties = message.getMessageProperties();
            messageProperties.setMessageId(UUID.randomUUID().toString());
            return message;
        };
        String title = "我是生产者";
        rabbitTemplate.convertAndSend(DirectExchangeConfig.DIRECT_EXCHANGE, DirectExchangeConfig.DIRECT_ROUTING_KEY, title, messagePostProcessor);
    }

    @RabbitHandler
    @RabbitListener(queues = DirectExchangeConfig.DIRECT_QUEUE1)
    public void process(String title, Message message) {
        String key = "rabbitmq_messageId:";
        String messageId = message.getMessageProperties().getMessageId();//生产者的UUID
        //使用set集合来做幂等性
        Long add = redisTemplate.opsForSet().add(key,messageId);
        if (add > 0) { //没有被消费
            System.out.println("消息正常消费---------------"+title);
        }else{
            System.out.println("该消息已经被消费,无法再次进行消费!");
        }

        //使用setnx命令来做幂等性
        if(redisTemplate.opsForValue().setIfAbsent(key + messageId, messageId,5L, TimeUnit.MINUTES)){
            System.out.println("消息正常消费---------------"+title);
        }else{
            System.out.println("该消息已经被消费,无法再次进行消费!");
        }

    }
}

如果24小时不间断的都会有消息来进行消费

需要思考的问题:

1、何时清理set集合中的缓存

2、setnx命令如何设置超时时间才合理

3、消息量过大的情况下每次生成UUID会不会影响性能

你可能感兴趣的:(Java,java-rabbitmq,rabbitmq,redis)