springboot监听redisKey过期

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-alpine
    container_name: redis-expiry
    ports:
      - "6379:6379"
    volumes:
      - ./config/redis.conf:/usr/local/etc/redis/redis.conf
      - ./data:/data
    command: redis-server /usr/local/etc/redis/redis.conf
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 30s
      retries: 3
    restart: unless-stopped

启动命令:

docker-compose up

实现步骤:

  1. 开启Redis的键空间通知功能:默认情况下,Redis是关闭这个功能的,需要修改Redis配置文件(redis.conf)或者通过命令行开启。
  2. 配置Spring Boot项目:添加相关依赖。
  3. 配置Redis消息监听容器:在Spring Boot中配置一个监听容器,并订阅__keyevent@*__:expired通道。
  4. 创建监听器:创建一个监听器来处理接收到的过期事件消息。

步骤一:开启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 {
    @Bean
    RedisMessageListenerContainer 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;
    }
    @Bean
    MessageListenerAdapter 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);
    @Override
    public void onMessage(Message message, byte[] pattern) {
        // 当接收到key过期事件时,会调用此方法
        String expiredKey = message.toString();
        logger.info("过期的key为:{}", expiredKey);
        // 在这里处理你的业务逻辑
    }
}
posted @ 2025-08-11 20:43  wds09  阅读(133)  评论(0)    收藏  举报