基于redis实现延时队列(二)

背景

上篇文章中使用了redis的zset+定时器实现延时任务,虽然定时器设置为30秒执行一次,但是还是有时间上的差异化;现更换一种方式实现,可以避免时间上的差异。
redis的key过期回调事件,也能达到延迟队列效果

配置修改

redis的key过期回调事件:我们需要修改配置,监听key是否过期,若过期则会触发一个callback事件
修改redis.conf文件开启 notify-keyspace-events Ex
基于redis实现延时队列(二)_第1张图片

代码演示

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实现延时队列(二)_第2张图片
该方式运用redis的key过期回调,可以避开定时器;从而让程序员更专注于自己的业务代码,另一方面也解决了时间差异的问题。

你可能感兴趣的:(数据库,redis,数据库)