目录
一、前言
redis 监听key失效回调事件是一个非常有用的监听事件。本文就来快速实现一下。下面将会介绍两种版本,一种是Springboot的版本,另一种是Spring的版本。
二、原理解释一波
原理很简单,采用了Redis自带的订阅/发布结构。当key失效之后,会向同一个库的 __keyevent@0__:expired 主题发布一个订阅信息,信息内容就是失效的key。
因此监听key失效的实现就就就就就很简单了。
还品不出来?我们订阅这个主题不就能获取到了失效事件?
三、Redis安装
略过。你连Redis都没有?
四、修改redis配置
window版本,打开redis根目录下redis.windows-service.conf
Crtl+F 搜索notify,找到892行这个notify0keyspace-events 后面修改为Ex,如图。
解释丢在这里。不会吧不会吧,不会还有人读不懂英文吧?
算了,我还是提一下吧。🐶头保命
K:keyspace 事件,事件以 keyspace@ 为前缀进行发布
E:keyevent 事件,事件以 keyevent@ 为前缀进行发布
g:一般性的,非特定类型的命令,比如del,expire,rename等
$:字符串特定命令
l:列表特定命令
s:集合特定命令
h:哈希特定命令
z:有序集合特定命令
x:过期事件,当某个键过期并删除时会产生该事件
e:驱逐事件,当某个键因 maxmemore 策略而被删除时,产生该事件
A:g$lshzxe的别名,因此”AKE”意味着所有事件
linux版本同理,修改redis.conf配置文件
小提一下,重要: docker镜像redis 默认无配置文件,需要自己挂载。我这里也是没有挂载。所以不演示了。
重要的事情说三遍,重启Redis!重启Redis!重启Redis!
下面开始撸代码
五、Springboot项目
1.引入依赖
修改pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.添加配置
修改application.properties
spring.redis.port=6379 # 端口
spring.redis.host=127.0.0.1 # 主机地址
spring.redis.database=0 # 选择库
3.添加相关的类
简易配置redis。
@Configuration
public class RedisConfiguration {
@Autowired
private RedisConnectionFactory redisConnectionFactory;
@Autowired
private KeyExpiredListener keyExpiredListener;
@Bean
public RedisMessageListenerContainer redisMessageListenerContainer() {
RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();
redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory);
// 配置监听器监听的主题关联
Topic topic = new ChannelTopic("__keyevent@0__:expired");
redisMessageListenerContainer.addMessageListener(keyExpiredListener, topic);
return redisMessageListenerContainer;
}
}
写一个监听器。
@Component
public class KeyExpiredListener implements MessageListener {
private static Logger logger = LoggerFactory.getLogger(TestRecall.class);
//这里是回调函数失效的时候回调用这个函数
@Override
public void onMessage(Message message, byte[] pattern) {
logger.info("key 失效回调事件触发");
System.out.println(new String(message.getBody()));
System.out.println(new String(message.getChannel()));
System.out.println(new String(pattern));
}
}
4.测试
写一个测试类。
/**
* 实现ApplicationRunner接口
* 在springboot启动时会自动开启一个线程执行此run方法
*/
@Component
public class TestRecall implements ApplicationRunner {
private static Logger logger = LoggerFactory.getLogger(TestRecall.class);
@Autowired
private StringRedisTemplate redisTemplate;
@Override
public void run(ApplicationArguments args) throws Exception {
// 设置一个缓存,3秒后过期
redisTemplate.opsForValue().set("key", "大誌", 3, TimeUnit.SECONDS);
logger.info("设置缓存成功");
}
}
启动项目,三秒后可以看到控制台打印信息。
正式开发中,在监听器处理业务逻辑即可。
六、Spring项目
百度一搜,全部都是上面Springboot+Redis。Spring整合起来实在是 太累了。下面的步骤其实你应该已经配置好了,本来不想写的,还是把他们贴上。如果你已经可以对redis进行操作了,可以直接跳过配进入第五点订阅配置。
1.引入依赖
这里引入2020年7月10日能获取到的最新版本。为了方便测试,我导入了mvc,进行web测试。
当然可以不用,我们细看原理,归根结底都是redis的操作。手动往redis里加个3秒过期的缓存其实是一样的。
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>sprin