前序
使用场景:设备与MQTT进行交互时,在设备上线时设备是会通过电信号发送一个上线标识的Topic表示设备已上线,但是离线时很多可能是突然断电程序是不会给你一个下线通知的,但是你又需要确定设备的状态,这时则可以在Redis中创建一个Key用来当做设备上线的凭证,当设备离线一段时间后Key过期给订阅的程序反馈一个过期Key值,然后通过程序使其状态离线
今日内容
修改redis配置文件redis-cli 订阅消息jedis操作redis进行消息的订阅
正文
一、修改Redis配置文件
1.在redis.conf中修改参数 notify-keyspace-events
#查找redis.conf所在路径
find / -name redis.conf
#编辑文件
vi 文件路径
2.进入编辑界面后 notify-keyspace-events Ex
EX 表示expire 和 evicted 过期的时间监听
# 快速查找关键字
/notify-keyspace-events
按n查找下一个 , 按N查找上一个
找到notify-keyspace-events 设置成notify-keyspace-events Ex
#保存退出
:wq!
3.重启redis,让配置加载
查看redis进程,找到reids的进程将他干掉
#查看redis进程
ps -ef | grep redis
#杀死进程
kill 进程号
重新启动redis
#找到redis-server
find / -name redis-server
#进入redis-server所在目录
cd 文件路径
#后台启动redis
redis-server /home/redis/redis.conf (这个就是修改的配置文件地址)
好的,到这步就配置完毕了,接下来在redis-cli中测试一下是否订阅成功
二、 redis-cli 中测试订阅所有过期key
1.登录redis-cli
在刚才后台启动的redis-server的路径下输入一下代码
两种登录redis-cli的方式
第一种
redis-cli -h IP地址 -p redis端口号 -a 密码
第二种
redis-cli -h IP地址 -p redis端口号
#输入密码
auth 密码
2.订阅所有过期key
#也可以将* 改为redis库的编号
PSUBSCRIBE __keyevent@*__:expired
可以再开一个窗口来设置过期key
3.设置过期key
第一种方式
set key value
expire key 过期时间 (单位:秒)
第二种方式
setex key 过期时间 val
查看过期的方式
#显示还有多少秒过期
ttl key
#显示还有多少毫秒过期
pttl key
-1 永不过期 -2 已经过期
4.监听到的结果
当key过期时订阅端就展示了 k1、k2两个键的名称还有所在的库 这样订阅过期key的演示就完毕了现在就进入springBoot中正式调用此功能
三、Jedis中实现过期key订阅的功能
1.引入pom
我没有指定版本springboot适配,有需要的也可以自己指定jedis的版本
2.编写服务类
@Slf4j
public class RedisConfiguration {
@Bean(name= "jedisPool")
public JedisPool getPool() {
JedisPoolConfig poolConfig = new JedisPoolConfig();
//最大空闲数,默认是8
poolConfig.setMaxIdle(10);
//最大连接数,默认是8
poolConfig.setMaxTotal(10);
//从池中获取连接时是否测试连接的有效性
poolConfig.setTestOnBorrow(true);
//在连接对象创建时测试连接对象的有效性
poolConfig.setTestOnCreate(true);
JedisPool pool = new JedisPool(poolConfig, IP地址, 端口号, 过期时间, 密码);
//创建线程去监听redis的过期key
timingThread(pool.getResource());
return pool;
}
private void timingThread(Jedis jedis){
Executors.newSingleThreadExecutor().execute(() -> {
try{
if (messageSend!=null){
jedis.subscribe(new RedisSubscriptionReceive(messageSend),"__keyevent@0__:expired");
}
}catch (Exception e){
log.error("异常,等待重试 {}",e);
}finally {
jedis.close();
}
});
}
可以在这个继承JedisPubSub的类中来写具体的实现方法
/**
*发布订阅消息监听器
**/
@Slf4j
public class RedisSubscriptionReceive extends JedisPubSub {
@Override
public void onMessage(String channel, String message) {
log.info("接收redis发布的消息, 频道 {}, 接收到的消息 {}", channel, message);
}
@Override
public void onSubscribe(String channel, int subscribedChannels) {
log.info("订阅redis频道成功, 订阅频道: {}, 序号: {}", channel, subscribedChannels);
}
}
四、后记
按照这个流程是能实现消息的订阅的,但是如果长时间没有往订阅的一方发消息,那么连接就会断开,后续就算有过期的key产生也不会再往其中进行消息的发送了,查阅了一下网上的资料好像说是在redis.conf中更改 tcp-keepalive 参数设置更长的连接保活时间,但是我测试了一下好像并没有生效,如果各位兄弟们有好的解决办法可以评论留言一起实验一下
相关文章
发表评论