前言

有时候,在项目中我们需要设定一个未来时间点,当时间达到后才触发

方法1:定时任务不断轮询判断时间…

方法2:延时队列 (JDK延时队列 MQ)

方法3:使用Redis,将触发逻辑定义为RedisKey并设置过期时间,我们同时监听redis过期键,在Key过期后,我们会收到通知

本文讲的是监听Redis过期键监听这种方式

依赖

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

配置

配置Redis消息监听容器

@Component
public class RedisConfig {

    /**
     *
     * @author lei
     * @date 2022-09-25 22:06:38
     * @param connectionFactory
     * @return RedisMessageListenerContainer
     */
    @Bean
    public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        return container;
    }
}

过期键监听器

编写一个类交由spring管理并继承KeyExpirationEventMessageListener,一个项目中可有多个监听器实例

监听所有DB

@Component
@Log4j2
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {

    public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    /**
     * 坚挺到过期消息
     *
     * @param message key
     * @param pattern 消息事件
     * @return void
     * @author lei
     * @date 2022-09-27 10:17:54
     */
    @Override
    public void onMessage(Message message, byte[] pattern) {
        String expiredKey = message.toString();
        // 过期消息key:aaa.......pattern:__keyevent@*__:expired
        log.info("过期消息key:{}.......pattern:{}", expiredKey, new String(pattern, StandardCharsets.UTF_8));
    }
}

image-20221020163440574

监听指定的DB

进入我们继承的KeyExpirationEventMessageListener,其中一个方法为doRegister,里边默认使用了new PatternTopic("__keyevent@*__:expired"),* 标志着监听所有DB,如果我们有监听指定DB需求则可以根据此类对我们的过期监听器实例进行改造

image-20221020163013036

EX:监听指定DB 为 11,此配置添加后,只会监听11数据库的KEY过期事件

image-20221020164626273

@Component
@Log4j2
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {

    public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    @Override
    protected void doRegister(RedisMessageListenerContainer listenerContainer) {
        listenerContainer.addMessageListener(this, new PatternTopic("__keyevent@11__:expired"));
    }

    /**
     * 坚挺到过期消息
     *
     * @param message key
     * @param pattern 消息事件
     * @return void
     * @author lei
     * @date 2022-09-27 10:17:54
     */
    @Override
    public void onMessage(Message message, byte[] pattern) {
        String expiredKey = message.toString();
        // 过期消息key:aaa.......pattern:__keyevent@11__:expired
        log.info("过期消息key:{}.......pattern:{}", expiredKey, new String(pattern, StandardCharsets.UTF_8));
    }
}

image-20221020164640632

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐