redis监听缓存失效通知事件
Redis配置
先修改Redis配置
修改redis相关事件配置。找到redis配置文件redis.conf,查看“notify-keyspace-events”的配置项,如果没有,添加“notify-keyspace-events Ex”,如果有值,添加Ex,然后重启Redis。相关参数说明如下:
1 2 3 4 5 6 7 8 9 10 11
| K:keyspace事件,事件以__keyspace@<db>__为前缀进行发布; E:keyevent事件,事件以__keyevent@<db>__为前缀进行发布; g:一般性的,非特定类型的命令,比如del,expire,rename等; $:字符串特定命令; l:列表特定命令; s:集合特定命令; h:哈希特定命令; z:有序集合特定命令; x:过期事件,当某个键过期并删除时会产生该事件; e:驱逐事件,当某个键因maxmemore策略而被删除时,产生该事件; A:g$lshzxe的别名,因此”AKE”意味着所有事件。
|
redis客户端测试:
客户端1:
script1 2 3 4 5
| 127.0.0.1:6379> psubscribe __keyevent@0__:expired Reading messages... (press Ctrl-C to quit) 1) "psubscribe" 2) "__keyevent@0__:expired" 3) (integer) 1
|
keyevent@0:expired
解析:
- key 键
- event 事件
- @0 第0个数据库
- expired 过期
客户端2:
script1
| 127.0.0.1:6379> set a 111 ex 5
|
客户端1:
script1 2 3 4
| 1) "pmessage" 2) "__keyevent@0__:expired" 3) "__keyevent@0__:expired" 4) "a"
|
java代码
配置Redis监听类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| @Slf4j @Configuration public class BeanConfig {
@Bean public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory);
return container; }
|
Redis监听类
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42
|
@Slf4j @Component public class ListenRedisKeyFailure extends KeyExpirationEventMessageListener { public ListenRedisKeyFailure(RedisMessageListenerContainer listenerContainer) { super(listenerContainer); }
private static final Topic KEYEVENT_EXPIRED_TOPIC = new PatternTopic("__keyevent@8__:expired");
@Override protected void doRegister(RedisMessageListenerContainer listenerContainer) { listenerContainer.addMessageListener(this, KEYEVENT_EXPIRED_TOPIC); }
@Override public void onMessage(Message message, byte[] pattern) { String expiredKey = message.toString(); if (expiredKey.startsWith("test:")) { log.info("Redis 过期的 Key:{}", expiredKey); } } }
|
测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @SpringBootTest class RedisListenKeyFailureApplicationTests {
@Autowired RedisTemplate<String, Object> redisTemplate;
@Test void redisKey() throws InterruptedException { redisTemplate.opsForValue().set("test:1", "", 2, TimeUnit.SECONDS); Thread.sleep(50000); } }
|