SpringBoot使用Jedis的订阅功能,监听Redis中的过期的Key

前序

使用场景:设备与MQTT进行交互时,在设备上线时设备是会通过电信号发送一个上线标识的Topic表示设备已上线,但是离线时很多可能是突然断电程序是不会给你一个下线通知的,但是你又需要确定设备的状态,这时则可以在Redis中创建一个Key用来当做设备上线的凭证,当设备离线一段时间后Key过期给订阅的程序反馈一个过期Key值,然后通过程序使其状态离线

今日内容

  1. 修改redis配置文件
  2. redis-cli 订阅消息
  3. 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的版本

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

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值