14 如何监听key过期时间并触发后置逻辑

vvEcho 2024-02-19 12:33:39
Categories: Tags:

1. 修改redisp配置,开启过期事件监听

1
notify-keyspace-events Ex  # 仅监听键过期事件(Ex=Expired events)

2. springboot配置监听器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@Configuration
public class RedisConfig {
@Bean
public RedisMessageListenerContainer container(RedisConnectionFactory factory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(factory);
return container;
}
}

@Configuration
public class RedisConfig {
@Bean
public RedisMessageListenerContainer container(RedisConnectionFactory factory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(factory);
// 订阅特定Key的过期事件(数据库0)
container.addMessageListener((message, pattern) -> {
String key = new String(message.getBody());
if (key.equals("mykey")) {
// 触发后置逻辑
}
}, new PatternTopic("__keyspace@0__:mykey"));
// 订阅所有数据库的过期事件
// container.addMessageListener(listener, new PatternTopic("__keyevent@*__:expired"));
return container;
}
}

3.监听器实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Component
public class KeyExpiredListener extends KeyExpirationEventMessageListener {
public KeyExpiredListener(RedisMessageListenerContainer listenerContainer) {
super(listenerContainer);
}

@Override
public void onMessage(Message message, byte[] pattern) {
String expiredKey = message.toString();
// 触发后置逻辑(如订单关闭、资源清理)
handleExpiredKey(expiredKey);

// if ("mykey".equals(expiredKey)) { // 仅处理目标Key
// handleExpiredKey(expiredKey);
// }
}
}

tips:需要注意集群模式下,每个服务都会收到过期事件,所以结合锁机制及数据库状态的二次校验保证监听的可靠性;