如何监听Redis中Key值的变化(SpringBoot整合)

 更新时间:2024年03月29日 08:48:00   作者:Z灏  
测试过程中我们有一部分常量值放入redis,共大部分应用调用,但在测试过程中经常有人会清空redis,回归测试,下面这篇文章主要给大家介绍了关于如何监听Redis中Key值变化的相关资料,需要的朋友可以参考下

一、概念

当Redis中的值发生改变时,通过配置来监听key值的变化。

事件通过 Redis 的订阅与发布功能(pub/sub)来进行分发, 因此所有支持订阅与发布功能的客户端都可以在无须做任何修改的情况下, 直接使用键空间通知功能。

二、配置

因为开启键空间通知功能需要消耗一些 CPU , 所以在默认配置下, 该功能处于关闭状态。

可以通过修改 redis.conf 文件, 或者直接使用 CONFIG SET 命令来开启或关闭键空间通知功能。
notify-keyspace-events 的参数可以是以下字符的任意组合, 它指定了服务器该发送哪些类型的通知:

第一种方式:直接使用命令

第一步:开启

config set notify-keyspace-events KEA

第二步:订阅

另起一个窗口,用于监听。

psubscribe '__key*__:*'                   #对所有库键空间通知
psubscribe '__keyspace@5__:*'             #是对db5数据库键空间通知
psubscribe '__keyspace@5__:order*'        #是对db5数据库,key前缀为order所有键的键空间通知

出现以上形式表明订阅成功。

第三步:添加数据

set k1 v1

这就是配置成功了。

【推荐】第二种方式:修改配置文件

如果使用第一种方式的话,当关闭窗口时,再次使用的话,还需要重新输入,而修改配置文件则不用重复操作。

第一步:找配置文件

在安装的路径中找到redis.windows.conf

点击快捷键"ctrl+F",输入:notify-keyspace-events

第二步:修改配置文件

改为:notify-keyspace-events KEA

点击"ctrl+S"保存并关闭

第三步:使用命令启动Redis

将Redis注册成一个服务启动,这样就不用每次开机手动启动了,而且不用一直用黑窗口打开了。

找到Redis的安装路径,然后进入,输入cmd

输入命令:

redis-server.exe --service-install redis.windows.conf 

这样在服务中就可以找到了。

三、整合SpringBoot

1.加入依赖

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2.配置文件

spring:
    redis:
        # Redis服务器地址
        host: 127.0.0.1
        # Redis服务器端口号
        port: 6379
        # 使用的数据库索引,默认是0
        database: 0
        # 连接超时时间
        timeout: 1800000
        # 设置密码
        password: 
        lettuce:
            pool:
                # 最大阻塞等待时间,负数表示没有限制
                max-wait: -1
                # 连接池中的最大空闲连接
                max-idle: 5
                # 连接池中的最小空闲连接
                min-idle: 0
                # 连接池中最大连接数,负数表示没有限制
                max-active: 20

3.配置类

package com.redisDemo.config;

import com.example.redisDemo.controller.RedisReceiver;
import com.example.redisDemo.listener.*;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.net.UnknownHostException;

/**
 * @author lenovo
 */
@Configuration
public class RedisConfig {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private RedisUpdateAndAddListener redisUpdateAndAddListener;

    @Autowired
    private RedisDeleteListener redisDeleteListener;

    @Autowired
    private RedisHashUpdateAndAddListener redisHashUpdateAndAddListener;

    @Autowired
    private RedisListUpdateAndAddListener redisListUpdateAndAddListener;

    @Autowired
    private RedisSetUpdateAndAddListener redisSetUpdateAndAddListener;

    @Autowired
    private RedisSortUpdateAndAddListener redisSortUpdateAndAddListener;


    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        //监听所有的key的set事件
        container.addMessageListener(redisUpdateAndAddListener, redisUpdateAndAddListener.getTopic());
        //监听所有key的删除事件
        container.addMessageListener(redisDeleteListener,redisDeleteListener.getTopic());
        container.addMessageListener(redisHashUpdateAndAddListener,redisHashUpdateAndAddListener.getTopic());
        container.addMessageListener(redisListUpdateAndAddListener,redisListUpdateAndAddListener.getTopic());
        container.addMessageListener(redisSetUpdateAndAddListener,redisSetUpdateAndAddListener.getTopic());
        container.addMessageListener(redisSortUpdateAndAddListener,redisSortUpdateAndAddListener.getTopic());
        //监听所有key的过期事件
//        container.addMessageListener(redisExpiredListener,redisExpiredListener.getTopic());
        return container;
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
        // 创建模板
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        // 设置连接工厂
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // 设置序列化工具
        GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        // key和 hashKey采用 string序列化
        redisTemplate.setKeySerializer(RedisSerializer.string());
        redisTemplate.setHashKeySerializer(RedisSerializer.string());

        // value和 hashValue采用 JSON序列化
        redisTemplate.setValueSerializer(RedisSerializer.string());
        redisTemplate.setHashValueSerializer(RedisSerializer.string());
        return redisTemplate;
    }
}

4.监听类

监听所有类型的删除操作:

package com.redisDemo.listener;

import lombok.Data;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.stereotype.Component;

@Component
@Data
public class RedisDeleteListener implements MessageListener {
 
    //监听主题
    private  final PatternTopic topic = new PatternTopic("__keyevent@*__:del");
 
    /**
     *
     * @param message 消息
     * @param pattern 主题
     */
    @Override
    public void onMessage(Message message, byte[] pattern) {
        String topic = new String(pattern);
        String msg = new String(message.getBody());
        System.out.println("收到key的删除,消息主题是:"+ topic+",消息内容是:"+msg);
    }
}

监听hash类型新增/修改: 

package com.redisDemo.listener;

import lombok.Data;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.stereotype.Component;

@Component
@Data
public class RedisHashUpdateAndAddListener implements MessageListener {
	//监听的主题
    private  final PatternTopic topic = new PatternTopic("__keyevent@*__:hset");
 
    @Override
    public void onMessage(Message message, byte[] pattern){
        String topic = new String(pattern);
        String msg = new String(message.getBody());
        System.out.println("收到key更新或修改,消息主题是:"+ topic+",消息内容是:"+msg);
    }
 
}

监听list类型的添加/修改: 

package com.redisDemo.listener;

import lombok.Data;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.stereotype.Component;

@Component
@Data
public class RedisListUpdateAndAddListener implements MessageListener {
	//监听的主题
    private  final PatternTopic topic = new PatternTopic("__keyevent@*__:lpush");
 
    @Override
    public void onMessage(Message message, byte[] pattern){
        String topic = new String(pattern);
        String msg = new String(message.getBody());
        System.out.println("收到key更新或修改,消息主题是:"+ topic+",消息内容是:"+msg);
    }
 
}

 监听set类型新增/修改:

package com.redisDemo.listener;

import lombok.Data;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.stereotype.Component;

@Component
@Data
public class RedisSetUpdateAndAddListener implements MessageListener {
	//监听的主题
    private  final PatternTopic topic = new PatternTopic("__keyevent@*__:sadd");
 
    @Override
    public void onMessage(Message message, byte[] pattern){
        String topic = new String(pattern);
        String msg = new String(message.getBody());
        System.out.println("收到key更新或修改,消息主题是:"+ topic+",消息内容是:"+msg);
    }
 
}

监听zset类型新增/修改: 

package com.redisDemo.listener;

import lombok.Data;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.stereotype.Component;

@Component
@Data
public class RedisSortUpdateAndAddListener implements MessageListener {
	//监听的主题
    private  final PatternTopic topic = new PatternTopic("__keyevent@*__:zadd");
 
    @Override
    public void onMessage(Message message, byte[] pattern){
        String topic = new String(pattern);
        String msg = new String(message.getBody());
        System.out.println("收到key更新或修改,消息主题是:"+ topic+",消息内容是:"+msg);
    }
 
}

监听string类型新增/修改: 

package com.redisDemo.listener;

import lombok.Data;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.stereotype.Component;

@Component
@Data
public class RedisUpdateAndAddListener implements MessageListener {
	//监听的主题
    private  final PatternTopic topic = new PatternTopic("__keyevent@*__:set");
 
    @Override
    public void onMessage(Message message, byte[] pattern){
        String topic = new String(pattern);
        String msg = new String(message.getBody());
        System.out.println("收到key更新或修改,消息主题是:"+ topic+",消息内容是:"+msg);
    }
 
}

5.启动项目

在Redis图形化界面添加一个数据

这下就成功监听到了。

如果没有监听到,请确保Redis正常启动了

总结

到此这篇关于如何监听Redis中Key值的变化的文章就介绍到这了,更多相关监听Redis中Key值变化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • linux部署redis集群遇到的问题及解决

    linux部署redis集群遇到的问题及解决

    Redis Cluster连接问题:使用127.0.0.1需改为公网IP;端口未开放(含总线端口)导致超时或等待;缺少-c参数引发MOVED错误
    2025-08-08
  • Redis 集群模式(Cluster)原理详解

    Redis 集群模式(Cluster)原理详解

    redis cluster集群是一个由多个主从节点集群组成的分布式服务集群,它具有复制、高可用和分片特性,cluster集群不需要sentinel 哨兵也能完成节点移除和故障转移的功能,本文就详细的给大家介绍一下Redis 集群模式原理,感兴趣的朋友跟着小编一起来看看吧
    2023-07-07
  • Redis在项目中的使用(JedisPool方式)

    Redis在项目中的使用(JedisPool方式)

    项目操作redis是使用的RedisTemplate方式,另外还可以完全使用JedisPool和Jedis来操作redis,本文给大家介绍Redis在项目中的使用,JedisPool方式,感兴趣的朋友跟随小编一起看看吧
    2021-12-12
  • Redis 热 Key 问题的解决

    Redis 热 Key 问题的解决

    热 Key是指在 Redis 中被高频访问的某个 Key,其访问频率远超其他 Key,导致该 Key 所在的 Redis 实例或节点成为系统瓶颈,下面就来介绍一下热key的问题解决,感兴趣的可以了解一下
    2026-02-02
  • redis如何后台启动的方法

    redis如何后台启动的方法

    这篇文章主要介绍了redis如何后台启动的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • Jedis操作Redis实现模拟验证码发送功能

    Jedis操作Redis实现模拟验证码发送功能

    Redis是一个著名的key-value存储系统,也是nosql中的最常见的一种,这篇文章主要给大家介绍Jedis操作Redis实现模拟验证码发送功能,感兴趣的朋友一起看看吧
    2021-09-09
  • 使用AOP+redis+lua做方法限流的实现

    使用AOP+redis+lua做方法限流的实现

    本文主要介绍了使用AOP+redis+lua做方法限流的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-04-04
  • Redis服务自动开启、设置密码和闪退问题及解决

    Redis服务自动开启、设置密码和闪退问题及解决

    本文介绍了如何在Windows上设置和配置Redis密码、实现Redis服务自动开启以及解决Redis闪退问题的方法和步骤
    2025-12-12
  • Redis安装与使用方法小结

    Redis安装与使用方法小结

    这篇文章主要介绍了Redis安装与使用方法,结合实例形式分析了Redis数据库的下载、安装、启动、设置及相关使用操作注意事项,需要的朋友可以参考下
    2018-04-04
  • Redis分布式锁的10个坑总结

    Redis分布式锁的10个坑总结

    日常开发中,经常会碰到秒杀抢购等业务,为了避免并发请求造成的库存超卖等问题,我们一般会用到Redis分布式锁,但是使用Redis分布式锁,很容易踩坑哦,本文将给大家分析阐述,Redis分布式锁的10个坑,需要的朋友可以参考下
    2023-05-05

最新评论