【Redis系列】Spring boot实现监听Redis key失效事件
talk is cheap, show me the code.
一、开启Redis key过期提醒
方式二:修改配置文件
redis.conf
# 默认 notify-keyspace-events ""
notify-keyspace-events Ex
方式二:命令行开启
CONFIG SET notify-keyspace-events Ex
CONFIG GET notify-keyspace-events
二、notify-keyspace-events
notify-keyspace-events 选项的默认值为空
notify-keyspace-events 的参数可以是以下字符的任意组合, 它指定了服务器该发送哪些类型的通知。
字符 | 发送的通知 |
---|---|
K | 键空间通知,所有通知以 keyspace@ 为前缀 |
E | 键事件通知,所有通知以 keyevent@ 为前缀 |
g | DEL 、 EXPIRE 、 RENAME 等类型无关的通用命令的通知 |
$ | 字符串命令的通知 |
l | 列表命令的通知 |
s | 集合命令的通知 |
h | 哈希命令的通知 |
z | 有序集合命令的通知 |
x | 过期事件:每当有过期键被删除时发送 |
e | 驱逐(evict)事件:每当有键因为 maxmemory 政策而被删除时发送 |
A | 参数 g$lshzxe 的别名 |
三、Coding
初始化一个
Spring Boot
项目pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
定义配置类
RedisListenerConfig
@Configuration
public class RedisListenerConfig { @Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
return container;
} }
定义数据生产类
ProviderDataToRedis
@Slf4j
@Component
public class ProviderDataToRedis implements CommandLineRunner { @Autowired
private StringRedisTemplate stringRedisTemplate; @Override
public void run(String... args) throws Exception {
int[] num = new int[]{1};
Random random = new Random();
while (true) {
int max = random.nextInt(5);
IntStream.range(0, max).forEach(n -> stringRedisTemplate.opsForValue().set(String.format("mq:s1:%s", ++num[0]), "已预订", 5, TimeUnit.SECONDS));
log.info("放了 {} 条数据到redis...", max);
TimeUnit.SECONDS.sleep(3);
}
}
}
定义监听器 实现
KeyExpirationEventMessageListener
接口查看源码发现,该接口监听所有db的过期事件
keyevent@*:expired"
定义
Status1ExpirationListener
监听状态1到期@Slf4j
@Component
public class Status1ExpirationListener extends KeyExpirationEventMessageListener { public Status1ExpirationListener(RedisMessageListenerContainer listenerContainer) {
super(listenerContainer);
} @Autowired
private StringRedisTemplate stringRedisTemplate; @Override
public void onMessage(Message message, byte[] pattern) {
// 用户做自己的业务处理即可,注意message.toString()可以获取失效的key
String expiredKey = message.toString();
if (expiredKey.startsWith("mq:s1:")) {
log.info("-----------------------------------");
log.info(String.format("过期key[%s]", expiredKey));
String newKey = String.format("mq:s2:%s", expiredKey.substring(6));
String newValue = "行程中";
stringRedisTemplate.opsForValue().set(newKey, newValue, 3, TimeUnit.SECONDS);
log.info(String.format("%s: %s", newKey, newValue));
log.info("-----------------------------------");
}
} }
定义
Status2ExpirationListener
监听状态2到期@Slf4j
@Component
public class Status2ExpirationListener extends KeyExpirationEventMessageListener { public Status2ExpirationListener(RedisMessageListenerContainer listenerContainer) {
super(listenerContainer);
} @Override
public void onMessage(Message message, byte[] pattern) {
// 用户做自己的业务处理即可,注意message.toString()可以获取失效的key
String expiredKey = message.toString();
if (expiredKey.startsWith("mq:s2:")) {
log.info("***********************************");
log.info(String.format("过期key[%s]", expiredKey));
log.info("[{}]行程已完成,修改数据库状态。", newKey);
log.info("***********************************");
}
} }
四、测试输出
...
2021-01-25 23:16:58.012 INFO 55511 --- [ main] n.y.tools.listener.ProviderDataToRedis : 放了 4 条数据到redis...
2021-01-25 23:17:00.037 INFO 55511 --- [ container-1070] c.i.r.l.Status1ExpirationListener : -----------------------------------
2021-01-25 23:17:00.037 INFO 55511 --- [ container-1070] c.i.r.l.Status1ExpirationListener : 过期key[mq:s1:272]
2021-01-25 23:17:00.037 INFO 55511 --- [ container-1072] c.i.r.l.Status1ExpirationListener : -----------------------------------
2021-01-25 23:17:00.037 INFO 55511 --- [ container-1072] c.i.r.l.Status1ExpirationListener : 过期key[mq:s1:271]
2021-01-25 23:17:00.039 INFO 55511 --- [ container-1070] c.i.r.l.Status1ExpirationListener : mq:s2:272: 行程中
2021-01-25 23:17:00.039 INFO 55511 --- [ container-1072] c.i.r.l.Status1ExpirationListener : mq:s2:271: 行程中
2021-01-25 23:17:00.039 INFO 55511 --- [ container-1070] c.i.r.l.Status1ExpirationListener : -----------------------------------
2021-01-25 23:17:00.039 INFO 55511 --- [ container-1072] c.i.r.l.Status1ExpirationListener : -----------------------------------
2021-01-25 23:17:00.140 INFO 55511 --- [ container-1075] c.i.r.l.Status2ExpirationListener : ***********************************
2021-01-25 23:17:00.140 INFO 55511 --- [ container-1075] c.i.r.l.Status2ExpirationListener : 过期key[mq:s2:270]
2021-01-25 23:17:00.140 INFO 55511 --- [ container-1075] c.i.r.l.Status2ExpirationListener : [270]行程已完成,修改数据库状态。
2021-01-25 23:17:00.140 INFO 55511 --- [ container-1075] c.i.r.l.Status2ExpirationListener : ***********************************
2021-01-25 23:17:00.242 INFO 55511 --- [ container-1077] c.i.r.l.Status2ExpirationListener : ***********************************
2021-01-25 23:17:00.242 INFO 55511 --- [ container-1077] c.i.r.l.Status2ExpirationListener : 过期key[mq:s2:269]
2021-01-25 23:17:00.242 INFO 55511 --- [ container-1079] c.i.r.l.Status2ExpirationListener : ***********************************
2021-01-25 23:17:00.242 INFO 55511 --- [ container-1079] c.i.r.l.Status2ExpirationListener : 过期key[mq:s2:268]
2021-01-25 23:17:00.242 INFO 55511 --- [ container-1077] c.i.r.l.Status2ExpirationListener : [269]行程已完成,修改数据库状态。
2021-01-25 23:17:00.242 INFO 55511 --- [ container-1077] c.i.r.l.Status2ExpirationListener : ***********************************
2021-01-25 23:17:00.242 INFO 55511 --- [ container-1079] c.i.r.l.Status2ExpirationListener : [268]行程已完成,修改数据库状态。
2021-01-25 23:17:00.242 INFO 55511 --- [ container-1079] c.i.r.l.Status2ExpirationListener : ***********************************
2021-01-25 23:17:00.546 INFO 55511 --- [ container-1081] c.i.r.l.Status2ExpirationListener : ***********************************
2021-01-25 23:17:00.546 INFO 55511 --- [ container-1081] c.i.r.l.Status2ExpirationListener : 过期key[mq:s2:267]
2021-01-25 23:17:00.546 INFO 55511 --- [ container-1081] c.i.r.l.Status2ExpirationListener : [267]行程已完成,修改数据库状态。
2021-01-25 23:17:00.546 INFO 55511 --- [ container-1081] c.i.r.l.Status2ExpirationListener : ***********************************
...
五、一直增加的线程数
从测试输出的日志中可以看出,线程一直在增加,这个问题还有待解决!
六、参考
http://redisdoc.com/topic/notification.html
【Redis系列】Spring boot实现监听Redis key失效事件的更多相关文章
- Spring boot实现监听Redis key失效事件实现和其它方式
需求: 处理订单过期自动取消,比如下单30分钟未支付自动更改订单状态 用户绑定隐私号码当订单结束取消绑定等 解决方案1: 可以利用redis自带的key自动过期机制,下单时将订单id写入redis,过 ...
- springboot redis 监听过期key值事件
redis 中的key值过期后,触发通知事件 1.创建springboot工程,创建监听类 maven配置 <dependencies> <dependency> <gr ...
- springboot使用Redis,监听Redis键过期的事件设置与使用代码
我使用的是Windows下的Redis服务,所以一下Redis设置都是在Windows平台进行. 1.修改Redis配置文件 1.1:Windows下的Redis存在两个配置文件 修改带有servic ...
- Spring Boot 如何快速集成 Redis 哨兵?
上一篇:Spring Boot 如何快速集成 Redis? 前面的分享栈长介绍了如何使用 Spring Boot 快速集成 Redis,上一篇是单机版,也有粉丝留言说有没有 Redis Sentine ...
- Spring Boot 2.x整合Redis
最近在学习Spring Boot 2.x整合Redis,在这里和大家分享一下,希望对大家有帮助. Redis是什么 Redis 是开源免费高性能的key-value数据库.有以下的优势(源于Redis ...
- Spring boot配置多个Redis数据源操作实例
原文:https://www.jianshu.com/p/c79b65b253fa Spring boot配置多个Redis数据源操作实例 在SpringBoot是项目中整合了两个Redis的操作实例 ...
- Spring Boot 多站点利用 Redis 实现 Session 共享
如何在不同站点(web服务进程)之间共享会话 Session 呢,原理很简单,就是把这个 Session 独立存储在一个地方,所有的站点都从这个地方读取 Session. 通常我们使用 Redis 来 ...
- 【spring boot】【redis】spring boot基于redis的LUA脚本 实现分布式锁
spring boot基于redis的LUA脚本 实现分布式锁[都是基于redis单点下] 一.spring boot 1.5.X 基于redis 的 lua脚本实现分布式锁 1.pom.xml &l ...
- 7、Spring Boot 2.x 集成 Redis
1.7 Spring Boot 2.x 集成 Redis 简介 继续上篇的MyBatis操作,详细介绍在Spring Boot中使用RedisCacheManager作为缓存管理器,集成业务于一体. ...
随机推荐
- 初识SylixOs
SylixOS 概述 SylixOS 是一款大型嵌入式实时操作系统,诞生于 2006 年,起初它只是一个小型多任务调度器,经过多年开发,SylixOS 目前已经成为一个功能完善.性能卓越.可靠稳定的嵌 ...
- Autofac官方文档翻译--一、注册组件--3属性和方法注入
官方文档:http://docs.autofac.org/en/latest/register/prop-method-injection.html Autofac 属性和方法注入 虽然构造函数参数注 ...
- 3.自定义view-TextView变色
1.效果 2.实现原理 自定义Textview,重写onDraw方法,将画布分成两部分,用不同颜色的画笔画 核心代码: @Override protected void onDraw(Canvas c ...
- 阿里云Ubuntu配置安装MQTT服务器
先来说说mqtt协议: MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议,它比较适合于在低带宽.不可靠的网络的进行远程 ...
- 备战金三银四!一线互联网公司java岗面试题整理:Java基础+多线程+集合+JVM合集!
前言 回首来看2020年,真的是印象中过的最快的一年了,真的是时间过的飞快,还没反应过来年就夸完了,相信大家也已经开始上班了!俗话说新年新气象,马上就要到了一年之中最重要的金三银四,之前一直有粉丝要求 ...
- 数据库索引的基石----B树
数据结构相对来说比较枯燥, 我尽量用最易懂的话,来把B树讲清楚.学过数据结构的人都接触过一个概念二叉树,简单来说,就是每个父节点最多有两个子节点.为了在二叉树上更快的进行元素的查找,人们通过不断的改进 ...
- ES6 对象拓展方法
一,ES6 对象拓展方法 ES6为对象提供了一些拓展方法,下面列举几个比较常见的对象拓展方法.
- post请求下载文件,获取Content-Disposition文件名
1.post下载文件代码,doload方法 import request from "../../src/utils/request"; import { API } from & ...
- 电脑加载有文件的CD、DVD驱动器图标修改
CD的图标有一定限制,不知道你说的是有盘状态还是默认的状态.插入光盘状态:用autorun.inf格式:[autorun]open=Install.exe 点击光盘时的起动程序icon=Autorun ...
- 风炫安全WEB安全学习第二十七节课 XSS的防御措施
风炫安全WEB安全学习第二十七节课 XSS的防御措施 XSS防御措施 总的原则 控制好输入/输出 过滤:根据业务需求进行过滤,对email,手机号码这样的输入框进行验证. 转义:所有输出到前端的数据都 ...