背景
上篇文章中使用了redis的zset+定时器实现延时任务,虽然定时器设置为30秒执行一次,但是还是有时间上的差异化;现更换一种方式实现,可以避免时间上的差异。
redis的key过期回调事件,也能达到延迟队列效果
配置修改
redis的key过期回调事件:我们需要修改配置,监听key是否过期,若过期则会触发一个callback事件
修改redis.conf文件开启 notify-keyspace-events Ex
代码演示
redis监听配置,注入监听容器 RedisMessageListenerContainer
@Configuration
public class RedisListenerConfig {
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
return container;
}
}
继承过期回调监听器KeyExpirationEventMessageListener
@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
super(listenerContainer);
}
@Override
public void onMessage(Message message, byte[] pattern) {
// 获取到失效的 key,进行相关业务处理
String expiredKey = message.toString();
System.out.println("key->" + expiredKey + "已过期");
}
}
代码编写完成,效果试验方法
@Autowired
RedisTemplate redisTemplate;
@ApiOperation(value = "测试")
@GetMapping(value = "/test")
public R test(){
redisTemplate.opsForValue().set("redisKey",1,30, TimeUnit.SECONDS);
return R.success();
}
30秒后控制台输出:
该方式运用redis的key过期回调,可以避开定时器;从而让程序员更专注于自己的业务代码,另一方面也解决了时间差异的问题。