通过开启key过期的事件通知,当key过期时,会发布过期事件;我们定义key过期事件的监听器,当key过期时,就能收到回调通知。

注意:

  • 由于redis key过期删除是定时+惰性,当key过多时,删除会有延迟,回调通知同样会有延迟。
  • 且通知是一次性的,没有ack机制,若收到通知后处理失败,将不再收到通知。需自行保证收到通知后处理成功。
  • 通知只能拿到key,拿不到value

使用场景

1、实现延时队列

    消息作为key,将需要延迟的时间设置为key的TTL,当key过期时,在监听器收到通知,达到延迟的效果。

使用步骤

1、修改redis 配置 加入一下配置

notify-keyspace-events Ex

2、配置 Message Listener Containers (消息订阅者容器)

Bean
public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory redisConnectionFactory) {
   // redis 消息订阅(监听)者容器
   RedisMessageListenerContainer messageListenerContainer = new RedisMessageListenerContainer();
   messageListenerContainer.setConnectionFactory(redisConnectionFactory);
   return messageListenerContainer;
}

3、定义 key过期监听器,继承 KeyExpirationEventMessageListener

/**
 * redis 监听过期key
 *
 * @author ruan
 */
@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
    /**
     * 创建RedisKeyExpirationListener bean时注入 redisMessageListenerContainer
     *
     * @param redisMessageListenerContainer RedisConfig中配置的消息监听者容器bean
     */
    public RedisKeyExpirationListener(RedisMessageListenerContainer redisMessageListenerContainer) {
        super(redisMessageListenerContainer);
    }

    @Override
    public void onMessage(Message message, byte[] pattern) {
        //redis中所有库的过期key 都会推送到这里,做业务需要时进行过滤,只处理需要的key 。
        String expiredKey = message.toString();
        System.out.println("监听到过期key:" + expiredKey);
    }
}

总结:依赖redis 可以实现一些简单的延时任务,且时间设置灵活。但是只能所有key过期都会通知,不能获取过期消息内容

文章目录