SpringBoot实现Redis失效监听事件—KeyExpirationEventMessageListener
Redis 监听过期的key(KeyExpirationEventMessageListener)
十三.Redis监听Key的过期事件
项目背景
需求上说,需要延迟半小时才能更新数据状态。问过架构,说项目暂不支持rocketmq。评估过kafka,可惜支持度不够,如果要实现也会相当复杂。
最终考量使用 redission ,通过监听键失效事件实现延时更新状态效果
技术落地
引入pom
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>x</version>
</dependency>
还需要开启redis的配置项
在redis.conf配置文件中有个配置项:notify-keyspace-events " " ,默认是没有key的过期监听的,我们需要将其开启。这个很关键,不然redis不会触发key失效事件
notify-keyspace-events Ex
配置类
@Configuration
public class RedisConfig {
@Bean
public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory connectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
return container;
}
@Bean
public KeyExpirationEventMessageListener redisKeyExpirationListener(RedisMessageListenerContainer redisMessageListenerContainer){
return new KeyExpirationEventMessageListener(redisMessageListenerContainer);
}
}
redis,保存设置了过期时间的key
@Autowired
private RedissonClient redissonClient;
public void setExpiredKey(){
//添加分布式锁,避免重复设置相同key
RLock lock = redissonClient.getLock(lockKey);
if (lock.tryLock(5, 5, TimeUnit.SECONDS)) {
if (!redissonClient.getBucket(key).isExists()) {
//业务处理
redissonClient.getBucket(key).set(Constants.SHORTAGE_ORDER_BUCKET, 30, TimeUnit.MINUTES);
}
}
}
失效监听器listener
@Component
public class MyListener extends KeyExpirationEventMessageListener {
@Override
public void onMessage(Message message, byte[] pattern) {
//业务处理,调用相关方法对失效的key进行相关处理
}
}
但注意,这里会监听所有失效的key,所以需进行相关过滤
其实就是底层原理就是 订阅-发布模式