首页 > 数据库 >Spring Boot 监听 Redis Key 失效事件实现定时任务

Spring Boot 监听 Redis Key 失效事件实现定时任务

时间:2023-10-12 12:03:40浏览次数:39  
标签:过期 Spring redis springframework Key import org Redis


1、业务场景

我们以订单功能为例说明下:

生成订单后一段时间不支付订单会自动关闭。最简单的想法是设置定时任务轮询,但是每个订单的创建时间不一样,定时任务的规则无法设定,如果将定时任务执行的间隔设置的过短,太影响效率。

还有一种想法,在用户进入订单界面的时候,判断时间执行相关操作。方式可能有很多,在这里介绍一种监听 Redis 键值对过期时间来实现订单自动关闭。

2、实现思路

在生成订单时,向 Redis 中增加一个 KV 键值对,K 为订单号,保证通过 K 能定位到数据库中的某个订单即可,V 可为任意值。

假设,生成订单时向 Redis 中存放 K 为订单号,V 也为订单号的键值对,并设置过期时间为 30 分钟,如果该键值对在 30 分钟过期后能够发送给程序一个通知,或者执行一个方法,那么即可解决订单关闭问题。

实现:通过监听 Redis 提供的过期队列来实现,监听过期队列后,如果 Redis 中某一个 KV 键值对过期了,那么将向监听者发送消息,监听者可以获取到该键值对的 K,注意,是获取不到 V 的,因为已经过期了,这就是上面所提到的,为什么要保证能通过 K 来定位到订单,而 V 为任意值即可。拿到 K 后,通过 K 定位订单,并判断其状态,如果是未支付,更新为关闭,或者取消状态即可。

3、开启 Redis key 过期提醒

修改 redis 相关事件配置。找到 redis 配置文件 redis.conf,查看 notify-keyspace-events 配置项,如果没有,添加 notify-keyspace-events Ex,如果有值,则追加 Ex,相关参数说明如下:

K:keyspace 事件,事件以 keyspace@ 为前缀进行发布
E:keyevent 事件,事件以 keyevent@ 为前缀进行发布
g:一般性的,非特定类型的命令,比如del,expire,rename等
$:字符串特定命令
l:列表特定命令
s:集合特定命令
h:哈希特定命令
z:有序集合特定命令
x:过期事件,当某个键过期并删除时会产生该事件
e:驱逐事件,当某个键因 maxmemore 策略而被删除时,产生该事件
A:g$lshzxe的别名,因此”AKE”意味着所有事件

4、引入依赖

在 pom.xml 中添加 org.springframework.boot:spring-boot-starter-data-redis 依赖

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

5

相关配置

定义配置 RedisListenerConfig 实现监听 Redis key 过期时间

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;

@Configuration
public class RedisListenerConfig {

    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {

        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        return container;
    }
}

定义监听器 RedisKeyExpirationListener,实现KeyExpirationEventMessageListener 接口,查看源码发现,该接口监听所有 db 的过期事件 keyevent@*:expired"

import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;

/**
 * 监听所有db的过期事件__keyevent@*__:expired"
 */
@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {

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

    /**
     * 针对 redis 数据失效事件,进行数据处理
     * @param message
     * @param pattern
     */
    @Override
    public void onMessage(Message message, byte[] pattern) {

        // 获取到失效的 key,进行取消订单业务处理
        String expiredKey = message.toString();
        System.out.println(expiredKey);
    }
}


PS:防止找不到本篇文章,可以收藏点赞,方便翻阅查找哦

标签:过期,Spring,redis,springframework,Key,import,org,Redis
From: https://blog.51cto.com/zhongmayisheng/7825441

相关文章

  • Spring Boot 2.6.0 发布,一大波新特性,禁止了循环依赖,还有哪些更新
    1、默认禁止了循环依赖循环依赖大家都知道,也被折磨过,这下2.6.0的版本默认禁止了循环依赖,如果程序中出现循环依赖就会报错。当然并没有一锤子打死,也提供了开启允许循环依赖的配置,只需要在配置文件中开启即可:spring:main:allow-circular-references:true2、支持自定义脱敏规......
  • SpringBoot + SpringBatch + Quartz整合定时批量任务
    1、引言最近一周,被借调到其他部门,赶一个紧急需求,需求内容如下:PC网页触发一条设备升级记录(下图),后台要定时批量设备更新。这里定时要用到Quartz,批量数据处理要用到SpringBatch,二者结合,可以完成该需求。由于之前,没有用过SpringBatch,于是上网查了下资料,发现可参考的不是很多,于是只能去......
  • 第四节:Redis数据持久化机制(备份恢复)、缓存淘汰策略、主从同步原理、常见规范与优化
    一.数据持久化 1. 含义Redis提供了RDB和AOF两种持久化方式,默认开启的是RDB,如果需要AOF,需要手动修改配置文件进行开启。RDB:是一种对Redis存在内存中的数据周期性的持久化机制,将内存中的数据以快照的形式硬盘,实质上是fork了一个子进程在执行数据存储,采用的是二进制压......
  • 记一次Redis Cluster Pipeline导致的死锁问题
    作者:vivo互联网服务器团队-LiGang本文介绍了一次排查Dubbo线程池耗尽问题的过程。通过查看Dubbo线程状态、分析Jedis连接池获取连接的源码、排查死锁条件等方面,最终确认是因为使用了clusterpipeline模式且没有设置超时时间导致死锁问题。一、背景介绍RedisPipeline是一......
  • 报错解决:java.security.InvalidKeyException: Illegal key size(微信支付v3遇到的问
    前言在使用微信支付v3生成jar包后本地测试没有问题在开发小程序支付功能的时候:本地开发好好的,放在linux服务器上运行时碰到报错原因是因为微信支付256位秘钥加密解密策略 可能会导致某些jdk的版本加密解密出现问题解决首先观察你这个目录下的文件根据文件内容做判断看下......
  • 忽视日志吃大亏,手把手教你玩转 SpringBoot 日志
    一、日志重要吗程序中的日志重要吗?在回答这个问题前,笔者先说个事例:❝笔者印象尤深的就是去年某个同事,收到了客户反馈的紧急bug。尽管申请到了日志文件,但因为很多关键步骤没有打印日志,导致排查进度很慢,数个小时都没能排查到问题,也无法给出解决对策。导致了客户程序一直阻断,最......
  • 【Spring】BeanPostProcessor后置处理器
    BeanPostProcessor后置处理器可以在Bean初始化前后做一些事情,注意这里是bean的初始化,不是实例化,BeanPostProcessor是一个接口,里面提供了两个方法,分别为postProcessBeforeInitialization(初始化之前)和postProcessAfterInitialization(初始化之后),在方法入参中有两个参数,一个bean对象,一......
  • Spring MVC 与 Spring Webflux 性能测试,谁更强?
    如果你已经使用Spring一段时间或者是编程初学者,你一定听说过使用响应式编程比传统的线程池风格更好。自Spring诞生以来,开发者创建Java企业应用程序就变得更加容易。它提供了在企业环境中使用Java语言所需的一切,支持Groovy和Kotlin作为JVM上的替代语言,并且可以根据......
  • 安装redis
    1、下载redis下载地址:https://github.com/redis/redis/releases1、tar-zvxfredis-7.2.0.tar.gz2、cdredis-7.2.03、make4、makeinstallPREFIX=/usr/local/redis2、设置redis1、cpredis.conf/etc/redis.conf2、vim/etc/redis.conf#设置远程访问#bind127.0.......
  • PHP 操作redis 详细讲解转的
    phpredis是redis的php的一个扩展,效率是相当高有链表排序功能,对创建内存级的模块业务关系很有用;以下是redis官方提供的命令使用技巧:https://www.clw9335.com/gl/719374.html下载地址如下:https://github.com/owlient/phpredis(支持redis2.0.4)Redis::__construct构造函数$redi......