springboot监听redisKey过期
docker中redis配置过期事件开启
创建相关目录
mkdir -p conf,data
new-item redis.conf
new-item docker-compose.yml
编辑redis.conf
# Redis 配置文件
daemonize no
port 6379
bind 0.0.0.0# 开启键空间通知 - 只监听过期事件
notify-keyspace-events Ex# 日志配置
loglevel notice
logfile ""# 数据持久化
appendonly yes
appendfilename "appendonly.aof"
编辑docker-compose.yml
services:redis:image: redis:7.0-alpinecontainer_name: redis-expiryports:- "6379:6379"volumes:- ./config/redis.conf:/usr/local/etc/redis/redis.conf- ./data:/datacommand: redis-server /usr/local/etc/redis/redis.confhealthcheck:test: ["CMD", "redis-cli", "ping"]interval: 5stimeout: 30sretries: 3restart: unless-stopped
启动命令:
docker-compose up
实现步骤:
- 开启Redis的键空间通知功能:默认情况下,Redis是关闭这个功能的,需要修改Redis配置文件(redis.conf)或者通过命令行开启。
- 配置Spring Boot项目:添加相关依赖。
- 配置Redis消息监听容器:在Spring Boot中配置一个监听容器,并订阅
__keyevent@*__:expired通道。 - 创建监听器:创建一个监听器来处理接收到的过期事件消息。
步骤一:开启Redis的键空间通知
在Redis服务器上,需要设置notify-keyspace-events参数。可以通过修改redis.conf文件,添加或修改如下配置:
notify-keyspace-events Ex
或者通过命令行临时设置(重启后失效):
redis-cli config set notify-keyspace-events Ex
这里的Ex表示启用过期事件(keyevent)的发布。也可以使用Egx等,具体可参考Redis文档。
步骤二:添加依赖
在Spring Boot项目的pom.xml中添加Spring Data Redis和Jedis(或Lettuce)依赖。
如果使用Jedis:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><exclusions><exclusion><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId></exclusion></exclusions>
</dependency>
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId>
</dependency>
如果使用Lettuce(默认),则只需添加:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
步骤三:配置Redis监听容器
创建一个配置类,配置RedisMessageListenerContainer,并订阅过期事件。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;
@Configuration
public class RedisListenerConfig {@BeanRedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,MessageListenerAdapter listenerAdapter) {RedisMessageListenerContainer container = new RedisMessageListenerContainer();container.setConnectionFactory(connectionFactory);// 订阅所有库的key过期事件(__keyevent@*__:expired)container.addMessageListener(listenerAdapter, new ChannelTopic("__keyevent@0__:expired"));// 如果有多个库,可以继续添加,或者使用通配符订阅(但Redis不支持通配符订阅,需要每个库单独订阅)// 注意:Redis默认使用0-15号库,这里只监听了0号库return container;}@BeanMessageListenerAdapter listenerAdapter(RedisKeyExpirationListener receiver) {// 设置监听器处理消息的方法return new MessageListenerAdapter(receiver, "onMessage");}
}
注意:上面的配置只监听了0号库。如果需要监听多个库,需要为每个库分别添加监听,因为Redis的发布订阅是分库的。例如,监听1号库:new ChannelTopic("__keyevent@1__:expired")。
步骤四:创建监听器
创建一个监听器类,用于处理接收到的过期事件消息。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.stereotype.Component;
@Component
public class RedisKeyExpirationListener implements MessageListener {private static final Logger logger = LoggerFactory.getLogger(RedisKeyExpirationListener.class);@Overridepublic void onMessage(Message message, byte[] pattern) {// 当接收到key过期事件时,会调用此方法String expiredKey = message.toString();logger.info("过期的key为:{}", expiredKey);// 在这里处理你的业务逻辑}
}
