如何监听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值变化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • redis批量操作pipeline管道操作方法

    redis批量操作pipeline管道操作方法

    Redis本身是基于一个Request一个Response方式的同步请求,正常情况下,客户端发送一个命令,这篇文章主要介绍了redis批量操作pipeline管道,需要的朋友可以参考下
    2022-09-09
  • 详解redis集群的三种方式

    详解redis集群的三种方式

    Redis三种集群方式分别是主从复制,哨兵模式,Cluster集群,这篇文章主要介绍了redis集群的三种方式,本文给大家介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • redis服务如何启动

    redis服务如何启动

    这篇文章主要介绍了redis服务如何启动问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • 单线程Redis快的4 个原因总结

    单线程Redis快的4 个原因总结

    作为内存中数据存储,Redis 以其速度和性能着称,通常被用作大多数后端服务的缓存解决方案,但是,在内部,Redis 采用单线程架构,为什么单线程设计依然会有这么高的性能,在本文中,让我们深入探讨为什么 Redis 才有单线程架构
    2023-07-07
  • redis使用跳跃表而不是树的原因解析

    redis使用跳跃表而不是树的原因解析

    Redis中支持五种数据类型中有序集合Sorted Set的底层数据结构使用的跳跃表,为何不使用其他的如平衡二叉树、b+树等数据结构呢?这篇文章主要介绍了redis使用跳跃表而不是树的原因解析,需要的朋友可以参考下
    2024-02-02
  • Redis异步队列的实现及应用场景

    Redis异步队列的实现及应用场景

    异步队列是一种底层基于异步 I/O 模型的消息队列,用于在分布式系统中进行同步和异步的通讯和协作,本文主要介绍了Redis异步队列的实现及应用场景,感兴趣的可以了解一下
    2023-12-12
  • redis实现好友关注&消息推送的方法示例

    redis实现好友关注&消息推送的方法示例

    Redis作为一款开源的内存数据库,具有可靠性、速度快、易用性等优点,已经被广泛应用于开发实际项目中,本文主要介绍了redis实现好友关注&消息推送的方法示例,感兴趣的可以了解一下
    2023-10-10
  • 基于 Spring Aop 环绕通知实现 Redis 缓存双删功能(示例代码)

    基于 Spring Aop 环绕通知实现 Redis 缓存双删功能(示例代码)

    基于 spring aop 常规应用场景多是用于日志记录以及实现 redis 分布式锁,在 github 中也有项目是把它拿来当作缓存的异常捕捉,这篇文章主要介绍了基于 Spring Aop 环绕通知实现 Redis 缓存双删,需要的朋友可以参考下
    2022-08-08
  • redis for windows 6.2.6安装包最新步骤详解

    redis for windows 6.2.6安装包最新步骤详解

    这篇文章主要介绍了redis for windows 6.2.6安装包全网首发,使用Windows计划任务自动运行redis服务,文章给大家讲解的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • Redis缓存三大异常的处理方案梳理总结

    Redis缓存三大异常的处理方案梳理总结

    这篇文章主要介绍了Redis缓存三大异常的处理方案梳理总结,缓存方式,在提高数据查询效率、保护数据库等方面起到了不可磨灭的作用,但实际应用中,可能会出现一些Redis缓存异常的情况,下文对其方案总结需要的朋友可以参考一下
    2022-06-06

最新评论