redis的过期事件监听

1,523 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情

在实际的开发项目中,监听 key 的过期事件,应用非常广泛,例如:优惠券过期,处理各种超时事件等等。

一、使用redis key 过期通知,需开启key过期通知功能:

1、redis-cli客户端,执行:

config set notify-keyspace-events Ex

2、或者直接修改redis server 配置文件,开启keyt过期听通知配置

notify-keyspace-events Ex

二、添加依赖

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

三、添加配置yml文件

#Redis数据库
redis:
    database: 1
    host: 127.0.0.1
    password:
    port: 6378
    defaultExpireTime: 18000
    jedis:
        pool:
            max-idle: 8
            min-idle: 0
            max-active: 8
            max-wait: -1ms

四、创建配置类

在redis配置文件加入代码:

@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {

    RedisMessageListenerContainer container = new RedisMessageListenerContainer();
    container.setConnectionFactory(connectionFactory);
    return container;
}

redis监听容器设置连接管理。

五、创建redis过期监听器

//redis消息过期监听器
@Component
@Slf4j
public class RedisExpiredListener extends KeyExpirationEventMessageListener {
    public RedisExpiredListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    //过期触发方法
    @Override
    public void onMessage(Message message, byte[] pattern) {
        String expiredKey = message.toString();
        log.info("cation ---- key {} expired", expiredKey);
    }
}

六、测试,使用@PostConstruct注解,在项目启动时候往redis存入key:test:key:TOM HANKS:expired_time,过期事件20S,监听过期事件是否发生。

//测试监听redis的key过期
@PostConstruct
public void init(){
   log.info("start init()");
   redisTemplate.opsForValue().set("test:key:TOM HANKS:expired_time", "an", 20, TimeUnit.SECONDS);
}

最终,监听事件打印了对应日志信息,说明已经监听到过期事件。

七、另一种实现

创建监听器:


@Component("redisKeyExpirationListener")
@RequiredArgsConstructor
@Slf4j
public class RedisKeyExpirationListener implements MessageListener {

    private final StringRedisTemplate redisTemplate;

    @Override
    public void onMessage(Message message, byte[] bytes) {

        //  获取失效的key
        String expiredKey = message.toString();
        log.info("监听到Redis中:{}过期", expiredKey);
        //  指定key 的前缀=test:key:
        // 业务处理

    }
}

添加配置:

//注册一个redis的消息监听器给spring容器管理

@Configuration
public class RedisConfigListenerContainer {

    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
                                            MessageListener redisKeyExpirationListener){
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.addMessageListener(redisKeyExpirationListener, new PatternTopic("__keyevent@1__:expired"));
        return container;
    }
}

PatternTopic订阅过期事件,

*代表所有库

keyevent@1:expired
__keyevent必须以此开头;
@2 表示[监听]第二个数据库;
:expired 表示过期事件

经验证,同样达到监听效果。

八、注意

过期监听消息中返回的是,过期的键的key值,是没有返回value的。