如何監(jiān)聽Redis中Key值的變化(SpringBoot整合)
一、概念
當(dāng)Redis中的值發(fā)生改變時,通過配置來監(jiān)聽key值的變化。
事件通過 Redis 的訂閱與發(fā)布功能(pub/sub)來進(jìn)行分發(fā), 因此所有支持訂閱與發(fā)布功能的客戶端都可以在無須做任何修改的情況下, 直接使用鍵空間通知功能。
二、配置
因為開啟鍵空間通知功能需要消耗一些 CPU , 所以在默認(rèn)配置下, 該功能處于關(guān)閉狀態(tài)。
可以通過修改 redis.conf 文件, 或者直接使用 CONFIG SET 命令來開啟或關(guān)閉鍵空間通知功能。
notify-keyspace-events 的參數(shù)可以是以下字符的任意組合, 它指定了服務(wù)器該發(fā)送哪些類型的通知:

第一種方式:直接使用命令
第一步:開啟
config set notify-keyspace-events KEA

第二步:訂閱
另起一個窗口,用于監(jiān)聽。
psubscribe '__key*__:*' #對所有庫鍵空間通知 psubscribe '__keyspace@5__:*' #是對db5數(shù)據(jù)庫鍵空間通知 psubscribe '__keyspace@5__:order*' #是對db5數(shù)據(jù)庫,key前綴為order所有鍵的鍵空間通知

出現(xiàn)以上形式表明訂閱成功。
第三步:添加數(shù)據(jù)
set k1 v1


這就是配置成功了。
【推薦】第二種方式:修改配置文件
如果使用第一種方式的話,當(dāng)關(guān)閉窗口時,再次使用的話,還需要重新輸入,而修改配置文件則不用重復(fù)操作。
第一步:找配置文件
在安裝的路徑中找到redis.windows.conf
點擊快捷鍵"ctrl+F",輸入:notify-keyspace-events

第二步:修改配置文件
改為:notify-keyspace-events KEA
點擊"ctrl+S"保存并關(guān)閉
第三步:使用命令啟動Redis
將Redis注冊成一個服務(wù)啟動,這樣就不用每次開機手動啟動了,而且不用一直用黑窗口打開了。
找到Redis的安裝路徑,然后進(jìn)入,輸入cmd

輸入命令:
redis-server.exe --service-install redis.windows.conf
這樣在服務(wù)中就可以找到了。

三、整合SpringBoot
1.加入依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>2.配置文件
spring:
redis:
# Redis服務(wù)器地址
host: 127.0.0.1
# Redis服務(wù)器端口號
port: 6379
# 使用的數(shù)據(jù)庫索引,默認(rèn)是0
database: 0
# 連接超時時間
timeout: 1800000
# 設(shè)置密碼
password:
lettuce:
pool:
# 最大阻塞等待時間,負(fù)數(shù)表示沒有限制
max-wait: -1
# 連接池中的最大空閑連接
max-idle: 5
# 連接池中的最小空閑連接
min-idle: 0
# 連接池中最大連接數(shù),負(fù)數(shù)表示沒有限制
max-active: 203.配置類
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);
//監(jiān)聽所有的key的set事件
container.addMessageListener(redisUpdateAndAddListener, redisUpdateAndAddListener.getTopic());
//監(jiān)聽所有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());
//監(jiān)聽所有key的過期事件
// container.addMessageListener(redisExpiredListener,redisExpiredListener.getTopic());
return container;
}
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
// 創(chuàng)建模板
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
// 設(shè)置連接工廠
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 設(shè)置序列化工具
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.監(jiān)聽類
監(jiān)聽所有類型的刪除操作:
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 {
//監(jiān)聽主題
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+",消息內(nèi)容是:"+msg);
}
}監(jiān)聽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 {
//監(jiān)聽的主題
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+",消息內(nèi)容是:"+msg);
}
}監(jiān)聽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 {
//監(jiān)聽的主題
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+",消息內(nèi)容是:"+msg);
}
}監(jiān)聽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 {
//監(jiān)聽的主題
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+",消息內(nèi)容是:"+msg);
}
}監(jiān)聽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 {
//監(jiān)聽的主題
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+",消息內(nèi)容是:"+msg);
}
}監(jiān)聽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 {
//監(jiān)聽的主題
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+",消息內(nèi)容是:"+msg);
}
}5.啟動項目
在Redis圖形化界面添加一個數(shù)據(jù)


這下就成功監(jiān)聽到了。
如果沒有監(jiān)聽到,請確保Redis正常啟動了。
總結(jié)
到此這篇關(guān)于如何監(jiān)聽Redis中Key值的變化的文章就介紹到這了,更多相關(guān)監(jiān)聽Redis中Key值變化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- springboot+redis過期事件監(jiān)聽實現(xiàn)過程解析
- Spring Boot監(jiān)聽Redis Key失效事件實現(xiàn)定時任務(wù)的示例
- spring boot+redis 監(jiān)聽過期Key的操作方法
- SpringBoot如何整合redis實現(xiàn)過期key監(jiān)聽事件
- SpringBoot如何監(jiān)控Redis中某個Key的變化(自定義監(jiān)聽器)
- SpringBoot中使用Redis?Stream實現(xiàn)消息監(jiān)聽示例
- SpringBoot如何監(jiān)聽redis?Key變化事件案例詳解
- springboot整合redis過期key監(jiān)聽實現(xiàn)訂單過期的項目實踐
- SpringBoot監(jiān)聽Redis key失效事件的實現(xiàn)代碼
- SpringBoot使用Redis單機版過期鍵監(jiān)聽事件的實現(xiàn)示例
相關(guān)文章
Redisson如何解決redis分布式鎖過期時間到了業(yè)務(wù)沒執(zhí)行完問題
這篇文章主要介紹了Redisson如何解決redis分布式鎖過期時間到了業(yè)務(wù)沒執(zhí)行完問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-01-01
詳解Redis中的BigKey如何發(fā)現(xiàn)和處理
這篇文章主要為大家詳細(xì)介紹了Redis中的BigKey如何發(fā)現(xiàn)和處理,文中給大家詳細(xì)講解了BigKey危害和如何解決這些問題,文章通過代碼示例和圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-10-10
為什么RedisCluster設(shè)計成16384個槽
本文主要介紹了為什么RedisCluster設(shè)計成16384個槽,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-09-09

