介绍
Redis 键过期事件是 Redis 中非常有用的功能,可以在键过期时触发事件通知。这对于缓存失效、会话管理、定时任务等场景非常有用。
Redis配置
Redis 默认是没有启用键过期事件通知的,你需要通过配置来启用这个功能。可以通过修改 redis.conf 文件或者使用 CONFIG SET 命令来启用键过期事件通知。
notify-keyspace-events Ex
依赖
<!-- 操作redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
配置文件
spring:
redis:
host: localhost
port: 6379
#password: 用的本机的redis,并且我没有设置redis密码
database: 0
lettuce:
pool:
# 最大阻塞等待时间,负数表示没有限制
max-wait: -1
# 连接池中的最大空闲连接
max-idle: 5
# 连接池中的最小空闲连接
min-idle: 0
# 连接池中最大连接数,负数表示没有限制
写入键
@RestController
@RequiredArgsConstructor
public class BasicController {
private final StringRedisTemplate stringRedisTemplate;
@GetMapping("/hello")
public String hello() {
// 设置键值对,并指定过期时间为 10 秒
stringRedisTemplate.opsForValue().set("product:123", "dpc", Duration.ofSeconds(5));
// 获取值
String str = stringRedisTemplate.opsForValue().get("name");
System.out.println("Value: " + str);
return str;
}
}
配置监听器
@Configuration
public class RedisListenerConfig {
@Bean
public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory connectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
return container;
}
@Bean
public OrderKeyExpirationListener orderKeyExpirationListener(RedisMessageListenerContainer container) {
// 配置监听器只监听 `order:*` 键
OrderKeyExpirationListener listener = new OrderKeyExpirationListener(container);
container.addMessageListener(listener, new ChannelTopic("__keyevent@0__:expired"));
return listener;
}
@Bean
public SessionKeyExpirationListener sessionKeyExpirationListener(RedisMessageListenerContainer container) {
// 配置监听器只监听 `session:*` 键
SessionKeyExpirationListener listener = new SessionKeyExpirationListener(container);
container.addMessageListener(listener, new ChannelTopic("__keyevent@0__:expired"));
return listener;
}
@Bean
public ProductKeyExpirationListener productKeyExpirationListener(RedisMessageListenerContainer container) {
// 配置监听器只监听 `product:*` 键
ProductKeyExpirationListener listener = new ProductKeyExpirationListener(container);
container.addMessageListener(listener, new ChannelTopic("__keyevent@0__:expired"));
return listener;
}
}
按KEY监听
监听session键
@Slf4j
public class SessionKeyExpirationListener extends KeyExpirationEventMessageListener {
public SessionKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
super(listenerContainer);
}
@Override
public void onMessage(Message message, byte[] pattern) {
String key = message.toString();
if (key.startsWith("session:")) {
log.info("会话【" + key + "】已过期");
// 处理会话超时的逻辑
}
}
}
监听product键
@Slf4j
public class ProductKeyExpirationListener extends KeyExpirationEventMessageListener {
public ProductKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
super(listenerContainer);
}
@Override
public void onMessage(Message message, byte[] pattern) {
String key = message.toString();
if (key.startsWith("product:")) {
log.info("产品【" + key + "】已过期");
// 处理产品相关的超时逻辑
}
}
}
监听order键
public class OrderKeyExpirationListener extends KeyExpirationEventMessageListener {
public OrderKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
super(listenerContainer);
}
@Override
public void onMessage(Message message, byte[] pattern) {
String key = message.toString();
System.out.println(123);
if (key.startsWith("order:")) {
// 处理订单相关的超时逻辑
}
}
}