前序

使用场景:设备与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的版本

redis.clients

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 参数设置更长的连接保活时间,但是我测试了一下好像并没有生效,如果各位兄弟们有好的解决办法可以评论留言一起实验一下

相关文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: