spring boot+redis 监听过期Key的操作方法
前言:
在订单业务中,有时候需要对订单设置有效期,有效期到了后如果还未支付,就需要修改订单状态。对于这种业务的实现,有多种不同的办法,比如:
1、使用querytz,每次生成一个订单,就创建一个定时任务,到期后执行业务代码;
2、rabbitMq中的延迟队列;
3、对Redis的Key进行监控;
1、引入依赖
org.springframework.boot spring-boot-starter-data-redis
2、修改boot的redis配置
spring: #redis redis: database:0 host:127.0.0.1 password:redis_123456 port:6379
3、在服务器中修改redis.conf配置文件(原来notify-keyspace-events属性是""空的,我们只需要填上“Ex”就行了)
notify-keyspace-events"Ex"
4、创建一个Redis监控类,用于监控过期的key,该类需继承KeyExpirationEventMessageListener
importorg.slf4j.Logger;
importorg.slf4j.LoggerFactory;
importorg.springframework.data.redis.connection.Message;
importorg.springframework.data.redis.listener.KeyExpirationEventMessageListener;
importorg.springframework.data.redis.listener.RedisMessageListenerContainer;
importjava.nio.charset.StandardCharsets;
/**
*@program:SpringCloud
*@description:redisKey过期监听
*@author:zhangyi
*@create:2020-03-2414:14
*/
publicclassKeyExpiredListenerextendsKeyExpirationEventMessageListener{
publicKeyExpiredListener(RedisMessageListenerContainerlistenerContainer){
super(listenerContainer);
}
@Override
publicvoidonMessage(Messagemessage,byte[]pattern){
System.out.println("过期key:"+message.toString());
}
}
5、创建Redis配置类
importcom.zy.rabbitmq.base.Listener.KeyExpiredListener;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.context.annotation.Bean;
importorg.springframework.context.annotation.Configuration;
importorg.springframework.data.redis.connection.RedisConnectionFactory;
importorg.springframework.data.redis.listener.RedisMessageListenerContainer;
/**
*@program:SpringCloud
*@description:redis配置类
*@author:zhangyi
*@create:2020-03-2414:17
*/
@Configuration
publicclassRedisConfiguration{
@Autowired
privateRedisConnectionFactoryredisConnectionFactory;
@Bean
publicRedisMessageListenerContainerredisMessageListenerContainer(){
RedisMessageListenerContainerredisMessageListenerContainer=newRedisMessageListenerContainer();
redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory);
returnredisMessageListenerContainer;
}
@Bean
publicKeyExpiredListenerkeyExpiredListener(){
returnnewKeyExpiredListener(this.redisMessageListenerContainer());
}
}
6、这里提供一个redis工具类,用于存储值,获取值,获取过期时间等操作。
importorg.springframework.data.redis.core.RedisTemplate;
importorg.springframework.stereotype.Component;
importorg.springframework.util.CollectionUtils;
importjavax.annotation.Resource;
importjava.util.concurrent.TimeUnit;
/**
*redis工具类
*@AuthorZhangYi
*/
@Component
publicclassRedisUtil{
@Resource
privateRedisTemplateredisTemplate;
/**
*指定缓存失效时间
*
*@paramkey键
*@paramtime时间(秒)
*@return
*/
publicbooleanexpire(Stringkey,longtime){
try{
if(time>0){
redisTemplate.expire(key,time,TimeUnit.SECONDS);
}
returntrue;
}catch(Exceptione){
e.printStackTrace();
returnfalse;
}
}
/**
*根据key获取过期时间
*
*@paramkey键不能为null
*@return时间(秒)返回0代表为永久有效
*/
publiclonggetExpire(Stringkey){
returnredisTemplate.getExpire(key,TimeUnit.SECONDS);
}
/**
*判断key是否存在
*
*@paramkey键
*@returntrue存在false不存在
*/
publicbooleanhasKey(Stringkey){
try{
returnredisTemplate.hasKey(key);
}catch(Exceptione){
e.printStackTrace();
returnfalse;
}
}
/**
*删除缓存
*
*@paramkey可以传一个值或多个
*/
@SuppressWarnings("unchecked")
publicvoiddel(String...key){
if(key!=null&&key.length>0){
if(key.length==1){
redisTemplate.delete(key[0]);
}else{
redisTemplate.delete(CollectionUtils.arrayToList(key));
}
}
}
//============================String=============================
/**
*普通缓存获取
*
*@paramkey键
*@return值
*/
publicObjectget(Stringkey){
returnkey==null?null:redisTemplate.opsForValue().get(key);
}
/**
*普通缓存放入
*
*@paramkey键
*@paramvalue值
*@returntrue成功false失败
*/
publicbooleanset(Stringkey,Objectvalue){
try{
redisTemplate.opsForValue().set(key,value);
returntrue;
}catch(Exceptione){
e.printStackTrace();
returnfalse;
}
}
/**
*普通缓存放入并设置时间
*
*@paramkey键
*@paramvalue值
*@paramtime时间(秒)time要大于0如果time小于等于0将设置无限期
*@returntrue成功false失败
*/
publicbooleanset(Stringkey,Objectvalue,longtime){
try{
if(time>0){
redisTemplate.opsForValue().set(key,value,time,TimeUnit.SECONDS);
}else{
set(key,value);
}
returntrue;
}catch(Exceptione){
e.printStackTrace();
returnfalse;
}
}
}
7、测试。(这里开放两个接口,一个set值,并设置过期时间为10秒,一个获取值和过期时间,当到达过期时间,看是否回去到过期Key)
@GetMapping("/put")
publicStringdemo(){
redisUtil.set("name","zhangyi",10);
return"aaa";
}
@GetMapping("/get")
publicMapget(){
Mapm=newHashMap<>();
m.put("time",redisUtil.getExpire("name"));
m.put("val",redisUtil.get("name"));
returnm;
}
成功获取到了过期Key,这里乱码是因为boot集成的Redis存key或者value的时候,没有配置字符串序列化。没有配置的话是默认使用jdk本身的序列化的。
到此这篇关于springboot+redis监听过期Key的文章就介绍到这了,更多相关springboot+redis监听过期Key内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。