监听redis过期的key

本文介绍如何在Redis中配置监听过期键的功能,并通过Spring Boot实现了一个具体的监听类,用以处理过期的键值并执行相应的业务逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一:需要监听过期的redis keys

     在redis.conf 里添加 notify-keyspace-events "Ex" ,放到配置参数的最后。

 

二:不需要账号密码访问

     改变redis.conf 里的protected-mode 的属性值为 no

三:去掉绑定的地址

    在redis.conf 里注销掉 bind 127.0.0.1



./redis-service ../redis.conf &


客户端执行redis 命令。
 psubscribe __keyevent@*__:expired 


pubsub配置:

@Configuration
@Import( value = ServiceApplication.class )
public class PubsubConfiguration  {

/*    @Autowired
    private RedisClient redisClient;*/

    @Bean
    MessageListenerAdapter messageListener() {
        return new MessageListenerAdapter( new RedisMessageListener() );
    }


    @Autowired
    @Bean
    public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory ) {

        final RedisMessageListenerContainer container =
                new RedisMessageListenerContainer();
        container.setConnectionFactory( connectionFactory );
        container.addMessageListener( messageListener(), new ChannelTopic( "__keyevent@0__:expired" ) );

        return container;
    }

/*    @Bean
    public MessageListener listener() {
        return new RedisMessageListener();
    }*/
}


 springboot 启动类

@SpringBootApplication
@ComponentScan
public class ServiceApplication implements CommandLineRunner {

    private static Logger logger = LoggerFactory.getLogger(ServiceApplication.class);

    @Override
    public void run(String... strings) throws Exception {

    }

    public static void main(String[] args) throws Exception {
        ApplicationContext ctx = SpringApplication.run(ServiceApplication.class, args);
        SpringContextUtil.setApplicationContext(ctx);
        logger.info("service start success .....");
    }

}


监听类实现:

public class RedisMessageListener implements MessageListener {

    protected Logger logger = LoggerFactory.getLogger(RedisMessageListener.class);

    @Autowired
    private BookTableBo bookTableBo;
    @Autowired
    private CalledRecordBo calledRecordBo;

    @Autowired
    private MqService mqService;

    @Override
    public void onMessage(Message message, byte[] pattern) {
        String key = message.toString();
        try {
            System.out.println( "Message received: " + message.toString() );
            logger.info( "Message received: " + message.toString() );
            if(StringUtils.isNotBlank(key) && key.startsWith(RedisUtils.TABLE_PREFIX)){
                String[] tKey = key.split("_");
                if(tKey.length==7){
                    String traceID = UUID.randomUUID().toString();
                    Integer groupID = Integer.parseInt(tKey[2]);
                    Integer shopID = Integer.parseInt(tKey[3]);
                    long mealDate = Long.parseLong(tKey[4]);
                    Integer mealTimeTypeID = Integer.parseInt(tKey[5]);
                    Integer tableID = Integer.parseInt(tKey[6]);
                    String redisKey = new StringBuilder()
                            .append(groupID)
                            .append("_")
                            .append(shopID)
                            .append("_")
                            .append(mealDate)
                            .append("_")
                            .append(mealTimeTypeID)
                            .toString();
                    if(null == bookTableBo){
                        bookTableBo =(BookTableBo)  SpringContextUtil.getBean("bookTableBo");
                    }
                    if(null == mqService){
                        mqService =(MqService)  SpringContextUtil.getBean("mqService");
                    }
                    DataSourceContextHolder.setDataSourceType(Constants.DB_ROUTEKEY_PREFIX_READ + groupID);
                    List<Integer> userableUnLockTables = bookTableBo.userableUnLockTable(groupID,
                            shopID,
                            tableID,
                            traceID,
                            redisKey,
                            mealDate,
                            mealTimeTypeID);

                    List<MealTimeTableStatusMqVO> mealTimeTableStatusMqBeans = new ArrayList<>();
                    for (Integer one:userableUnLockTables){
                        mealTimeTableStatusMqBeans.add(MqUtils.buildMealTimeTableStatusMqBean(one, OrderStatusEnum.FREE.getStatus(),0L,0L,0,"",0,"",0));
                    }
                    mqService.sendMessToShop(shopID, MqUtils.buildUnTakeUpTableMq(traceID,mealDate,mealTimeTypeID,mealTimeTableStatusMqBeans));
                    mqService.sendTableStatusChangeMq(groupID,shopID,mealDate,mealTimeTypeID,userableUnLockTables,null);
                }
            }
        }catch (Exception e){
            logger.error("handler expire key error"+key,e);
        }
    }
	}

可以使用 Spring Data Redis 提供的 @EnableRedisRepositories 注解,同时实现 RedisKeyExpirationListener 接口,并在 @Configuration 类中添加监听器配置。 以下是代码片段示例: @Configuration @EnableRedisRepositories public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate() { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(jedisConnectionFactory()); return template; } @Bean public JedisConnectionFactory jedisConnectionFactory() { return new JedisConnectionFactory(); } @Bean public RedisMessageListenerContainer redisContainer() { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(jedisConnectionFactory()); return container; } @Bean RedisKeyExpirationListener keyExpirationListener() { return new RedisKeyExpirationListener(); } @Bean MessageListenerAdapter listenerAdapter(RedisKeyExpirationListener keyExpirationListener) { return new MessageListenerAdapter(keyExpirationListener); } @Bean RedisMessageListenerContainer keyExpirationContainer(RedisKeyExpirationListener keyExpirationListener, MessageListenerAdapter listenerAdapter) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(jedisConnectionFactory()); container.addMessageListener(listenerAdapter, new PatternTopic("__keyevent@*:expired")); return container; } private static class RedisKeyExpirationListener implements MessageListener { @Override public void onMessage(Message message, byte[] pattern) { String expiredKey = message.toString(); // 处理过期key逻辑 } } } 这里我们定义了一个 RedisContainer 和一个 RedisKeyExpirationListener,然后将 RedisKeyExpirationListener 获取到的过期 key 进行处理。ListenAdapter 和 keyExpirationContainer 主要是为了配置监听器,其中"__keyevent@*:expired"用来监听所有 Redis 中发生的 key 过期事件。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值