Redis key 失效通知配置及命令监听
2020-07-13 本文已影响0人
_大叔_
修改 redis.conf 配置
找到notify-keyspace-events 并将notify-keyspace-events 修改为 notify-keyspace-events Ex
![](https://img.haomeiwen.com/i13859779/7c2bcfdeae41fe18.png)
配置Ex对应的意思如下: E: 键事件通知,以keysevent@<db>为前缀 x:过期事件(每次key过期时生成)
- K 键空间通知,以keyspace@<db>为前缀
- E 键事件通知,以keysevent@<db>为前缀
- g del , expipre , rename 等类型无关的通用命令的通知, ...
- $ String命令
- l List命令
- s Set命令
- h Hash命令
- z 有序集合命令
- x 过期事件(每次key过期时生成)
- e 驱逐事件(当key在内存满了被清除时生成)
- A g$lshzxe的别名,因此”AKE”意味着所有的事件
notify-keyspace-events选项
服务器配置的notify-keyspace-events选项决定了服务器所发送通知的类型:
可以设置的类型如下:
想让服务器发送所有类型的键空间通知和键事件通知,可以将选项的值设置为AKE
想让服务器发送所有类型的键空间通知,可以将选项的值设置为AK
想让服务器发送所有类型的键事件通知,可以将选项的值设置为AE
想让服务器只发送和字符串键有关的键空间通知,可以将选项的值设置为K$
想让服务器只发送和列表键有关的键事件通知,可以将选项的值设置为El
备注:notify-keyspace-events选项的默认值为空,所以如果不设置上面的值,SUBSCRIBE命令不会有任何效果
其中原理就是使用了redis的发布订阅功能。
spring boot redis key 失效通知配置
添加配置类
package com.giant.cloud.config;
import com.giant.cloud.support.ReceiveNoticeMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author big uncle
* @date 2020/7/13 16:24
* @module
**/
@Configuration
@ConditionalOnBean(ReceiveNoticeMessage.class)
@Slf4j
public class RedisNoticeConfig {
@Value("${spring.redis.database:0}")
private Integer db;
@Autowired
ReceiveNoticeMessage receiveNoticeMessage;
/**
* 将 Receiver注册为一个消息监听器,并指定消息接收的方法(expiredMessage)
* 如果不指定消息接收的方法,消息监听器会默认的寻找Receiver中的handleMessage这个方法做为消息接收的方式
**/
@Bean
MessageListener messageListener(){
return new MessageListenerAdapter(receiveNoticeMessage(),"noticeMessage");
}
@Bean
ReceiveNoticeMessage receiveNoticeMessage(){
return receiveNoticeMessage;
}
/**
* 设置监听类型
**/
@Bean
public List<ChannelTopic> channelTopic(){
String name = "__keyevent@"+db.intValue()+"__:%s";
List<String> commands = Arrays.asList("set","lpush","expired");
return commands.stream().map(i -> new ChannelTopic(String.format(name,i))).collect(Collectors.toList());
}
/**
* 通过 RedisMessageListenerContainer 配置监听生效
**/
@Bean
public RedisMessageListenerContainer redisMessageListenerContainer(@Autowired RedisConnectionFactory redisConnectionFactory){
RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();
redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory);
redisMessageListenerContainer.addMessageListener(messageListener(),channelTopic());
return redisMessageListenerContainer;
}
}
接口
package com.giant.cloud.support;
/**
* @author big uncle
* @date 2020/7/13 17:13
**/
public interface ReceiveNoticeMessage {
/**
* 失效接收方法
* @author big uncle
* @date 2020/7/13 17:14
* @param key
* @param channel
* @return void
**/
void noticeMessage(String key,String channel);
}
实现类
package com.giant.cloud.monitor;
import com.giant.cloud.support.ReceiveNoticeMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* @author big uncle
* @date 2020/10/9 17:49
* @module
**/
@Component
@Slf4j
public class RedisKeyMonitor implements ReceiveNoticeMessage {
@Override
public void noticeMessage(String key,String channel) {
log.debug("key is {}, channel is {}",key,channel);
}
}