十三.Redis监听Key的过期事件

前言

试想一个业务场景,订单超过30分钟未支付需要做自动关单处理,修改订单状态,库存回退等,你怎么实现?方案一:可以使用定时任务扫表,通过支付状态和下单时间来判断是否支付过期。但是这样的方案是非常消耗性能的,因为大部分的定时扫表都是无效的,而且这种定时任务方案对于时间控制并不精确。

类似的业务场景还很多,比如物流自动收货确认,比如某电影上线预约功能的到时提醒等等,对于这些问题有没有比定时任务更优雅的处理方案呢?

在之前我写过一个《RabbitMQ的延迟队列》,可以用来解决这种业务场景,那如果项目中并没有用到RabbitMQ,为了搞一个延迟队列而使用RabbitMQ未免太麻烦,那么本篇文章《Redis监听key过期事件》就可以代替RabbitMQ的延迟队列来处理类似的场景。

开启key过期事件

在redis.conf配置文件中有个配置项:notify-keyspace-events " " ,默认是没有key的过期监听的,我们需要将其开启,如下:
在这里插入图片描述
这里的 EX代表 expire 和 evicted 过期和驱逐 的时间监听 ,注意:改了配置要重启Redis

创建SpringBoot工程

创建SpringBoot项目,导入Redis依赖

 <!--整合Redis , 底层可以用jedis-->
  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-redis</artifactId>
      <exclusions>
          <exclusion>
              <groupId>io.lettuce</groupId>
              <artifactId>lettuce-core</artifactId>
          </exclusion>
      </exclusions>
  </dependency>

  <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
  </dependency>

然后做yml配置,Redis基本配置

spring:
  redis:
    database: 0
    host: 127.0.0.1
    port: 6379
    password: 123456
    jedis:
      pool:
        max-wait: 2000ms
        min-idle: 2
        max-idle: 8

…其他不重要代码这里就省略了…

配置Redis监听器

注册 RedisMessageListenerContainer ,为Redis消息侦听器提供异步行为的容器

@Configuration
public class RedisConfig {

    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {

        //Redis消息监听器
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        //设置Redis链接工厂
        container.setConnectionFactory(connectionFactory);

        return container;
    }
}

定义key过期的监听器 通过继承 KeyExpirationEventMessageListener 来完成

//消息过期监听器
@Slf4j
@Component
public class RedisExpireListener extends KeyExpirationEventMessageListener {

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

    //当消息过期,触发方法
    @Override
    public void onMessage(Message message, byte[] pattern) {
        String expiredKey = message.toString();
        System.out.println("Key -> "+expiredKey +"过期了...");
    }
}

测试

使用redis-cli 设置一个带过期时间的 key ,如:
在这里插入图片描述
等待key过期,观察代码控制台
在这里插入图片描述

到这里文章就结束了,如果喜欢请给个好评吧!!!

  • 14
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

墨家巨子@俏如来

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值