Redis过期事件监听
2025/7/10大约 1 分钟
Redis过期事件监听
启用 Redis 的键空间通知
首先需要在 Redis 配置文件中启用键空间通知。找到或编辑 redis.conf
文件,添加以下配置:
notify-keyspace-events Ex
E
:表示启用键事件(Key event)通知。x
:表示启用过期事件(Expired key)通知。
如果使用 Docker 或命令行启动 Redis,可以直接传参:
redis-server --notify-keyspace-events Ex
Java 客户端配置
在 Spring Boot 项目中,使用 RedisTemplate
和 RedisMessageListenerContainer
来订阅 Redis 的过期事件。
配置 RedisTemplate
确保 RedisTemplate
已正确配置,例如:
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new StringRedisSerializer());
return template;
}
}
配置 Redis 消息监听器
编写一个监听器类,实现 MessageListener
接口,处理过期事件:
@Bean
public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory connectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
String database = environment.getProperty("spring.data.redis.database");
Topic topic = new PatternTopic("__keyevent@" + database + "__:expired");
container.addMessageListener((message, pattern) -> {
String expiredKey = new String(message.getBody()); // 获取过期的键
System.out.println("过期的键: " + expiredKey);
if (expiredKey.contains("heartbeat:server")) {
String[] s = expiredKey.split(":");
gatewayServerDetailMapper.offline(s[3] + ":" + s[4]);
} else if (expiredKey.contains("heartbeat:group")) {
String[] s = expiredKey.split(":");
gatewayGroupDetailMapper.offline(s[3] + ":" + s[4]);
}
}, topic);
return container;
}
设置带过期时间的键
@Autowired
private RedisTemplate<String, Object> redisTemplate;
public void setHeartbeat(String serviceId, int expireSeconds) {
String key = "heartbeat:group:" + serviceId;
redisTemplate.opsForValue().set(key, "alive", expireSeconds, TimeUnit.SECONDS);
}
等待键过期
等待键过期后,监听器会自动触发并打印日志:
过期的键: heartbeat:service:123