序:
这次遇到的场景是需要对redis的失效key做比对判断,增加电业务逻辑。
废话不多说,直接说重点,我也赶着回家呢。
redis配置文件修改,我是win系统。这个是对redis版本有要求的,所以先查看版本信息。
查看redis版本信息,redis安装目录下,黑框框(你懂的)下运行redis-cli.exe,然后再输入info
这个实际上是高版本的redis的消息队列的一种使用。redis版本要求2.8.0以上,我这里装的是3.2.100
redis配置文件修改,找到redis.windows.conf文件,用记事本类工具打开。
重启redis服务,注意要带配置文件哦,很多人起服务不带这个redis配置文件,所以每次重启里面的key都丢失了。
验证是否会有监听
还是在刚刚输入info命令的黑框框继续输入 psubscribe "__keyevent@*:expired",回车。你会看到
然后,配合redis Desktop Manager看效果,打开这个工具,连接上redis后,打开命令行
看到效果没,我在命令行输入用命令设置一个3秒超时的key value,然后黑框框3s后就有反应了。
上面讲的基本是原理,下面上java代码
springBoot增加一个配置,上次说到过redis增加配置,真是简单,方便的不要不要的,直接在config包下增加一个配置类RedisListenerConfig类,代码如下:
package com.filler.config;
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.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import com.filler.listenner.RedisExpiredListener;
@Configuration
public class RedisListenerConfig {
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
//下面这种方式是灵活配置,针对每个库的失效key做处理
//container.addMessageListener(new RedisExpiredListener(), new PatternTopic("__keyevent@0__:expired"));
return container;
}
}
然后我建了一个listenner的包,在下面增加一个监听类:
package com.filler.listenner;
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;
/**
* redis失效key监听
*
* @author 郑文
*
*/
@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
super(listenerContainer);
}
/**
* redis失效key事件处理
* @param message
* @param pattern
*/
@Override
public void onMessage(Message message, byte[] pattern) {
// message.toString()可以获取失效的key
String expiredKey = message.toString();
System.out.println("-------------------");
System.out.println("失效key:"+expiredKey);
}
}
还有一个监听类,是配合上面的配置文件注释的部分的,可以灵活配置,配置监听不同的库,redis有16个库。
package com.filler.listenner;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
public class RedisExpiredListener implements MessageListener {
@Override
public void onMessage(Message message, byte[] bytes) {
byte[] body = message.getBody();// 建议使用: valueSerializer
byte[] channel = message.getChannel();
System.out.print("onMessage >> " );
System.out.println(String.format("channel: %s, body: %s, bytes: %s"
,new String(channel), new String(body), new String(bytes)));
}
}
ok了,代码写完了,看看效果,还是用redis Desktop Manager配合java代码
看到效果了吧。然后你就可以在你的监听类里判断失效key的特征,写自己的业务逻辑。唯一遗憾的是不能难道value,也能够理解,实际就是redis删除失效key做了一个通知主题被java感知了。以后有个redis失效key的前置事件就好了。现在变相的处理方式,可以约定业务存2个key,一个有失效时间,一个没有,比如存win这个key时,还存一个win_val可以,在失效监听里自己再去取win_val的value消费,消费完成后删除这个win_val的key。
好了就到这里了,剩下的业务逻辑就可以fly your self了。