美文网首页SpringBoot微服务
SpringBoot实现Redis失效监听事件—KeyExpir

SpringBoot实现Redis失效监听事件—KeyExpir

作者: 小方块886 | 来源:发表于2021-06-07 09:20 被阅读0次

    使用场景:当redis某个key过期的时候,我们希望处理一些业务例如发消息或者取消订单等,当然也可以使用中间件mq来实现,之前的文章里有写rocketMq实现消息的通知和消费,这篇文章主要是用redis来实现

    1.引入依赖

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    

    yml配置

    spring:
      redis:
        host: 127.0.0.1
        port: 6379
        password: 123456
    

    2.配置文件

    @Configuration
    @EnableCaching
    public class RedisConfig extends CachingConfigurerSupport {
        /**
         * key过期事件订阅需要
         * @param redisConnectionFactory
         * @return
         */
        @Bean
        RedisMessageListenerContainer container(RedisConnectionFactory redisConnectionFactory) {
            RedisMessageListenerContainer container = new RedisMessageListenerContainer();
            container.setConnectionFactory(redisConnectionFactory);
            return container;
        }
    
    }
    

    3.自定义监听器,需要继承KeyExpirationEventMessageListener

    @Component
    public class RedisListener extends KeyExpirationEventMessageListener {
    
        @Autowired
        private StringRedisTemplate stringRedisTemplate;
    
        private final String SET_NX = "setnx:";
    
        public RedisListener(RedisMessageListenerContainer listenerContainer) {
            super(listenerContainer);
    
        }
    
        @Override
        public void onMessage(Message message, byte[] pattern) {
            // 获取过期的key,可以做自己的业务
            String expiredKey = message.toString();
            // 利用redis setIfAbsent命令,如果为空set返回true,如果不为空返回false,类似setnx加锁操作
            Boolean aBoolean = stringRedisTemplate.opsForValue().setIfAbsent(SET_NX + expiredKey, String.valueOf(System.currentTimeMillis()),10, TimeUnit.SECONDS);
            if (aBoolean){
                // 避免多个服务监听情况下重复消费
                // 注意:只能获取失效的key值,不能获取key对应的value值
                System.out.println(expiredKey);
            }
        }
    }
    

    我们需要重写onMessage方法,当有key过期的时候这个方法可以获取获取的key,并处理自己的业务
    如果我们是多台机器部署,那么我们还需要加锁操作,避免消息的重复消费,这里利用了stringRedisTemplate.opsForValue().setIfAbsent命令可以帮我们完成setnx加锁的操作,如果为空set返回true,如果不为空返回false,因为redis是单线程所以可以保证只消费一次,setIfAbsent同时要加上过期时间,注意redis版本过低的话可能没有这个方法

    相关文章

      网友评论

        本文标题:SpringBoot实现Redis失效监听事件—KeyExpir

        本文链接:https://www.haomeiwen.com/subject/rudosltx.html