https://blog.csdn.net/weixin_41497481/article/details/85322794
场景:
redis缓存中的缓存过期了,但是还需要用到他,然而如果设置缓存为永不过期的话,数据会越堆越多,严重占用空间。所以需要对过期缓存进行监听。在缓存过期的时候进行处理。如果还需要用到就重新加载缓存,用不到了可以不用处理。解决了有用缓存过期的尴尬,又不会造成数据堆积。
过期事件通过Redis的订阅与发布功能(pub/sub)来进行分发。
配置文件
而对超时的监听呢,并不需要自己发布,只有修改配置文件redis.conf中的:notify-keyspace-events Ex,默认为notify-keyspace-events ""
# K 键空间通知,以__keyspace@<db>__为前缀
# E 键事件通知,以__keysevent@<db>__为前缀
# g del , expipre , rename 等类型无关的通用命令的通知, ...
# $ String命令
# l List命令
# s Set命令
# h Hash命令
# z 有序集合命令
# x 过期事件(每次key过期时生成)
# e 驱逐事件(当key在内存满了被清除时生成)
# A g$lshzxe的别名,因此”AKE”意味着所有的事件
监听器:
-
package connect.listen;
-
import org.springframework.data.redis.connection.MessageListener;
-
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
-
import org.springframework.data.redis.listener.PatternTopic;
-
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
-
import org.springframework.data.redis.listener.Topic;
-
/**
-
* @author wm
-
*/
-
public class KeyExpirationEvent5MessageListener extends KeyExpirationEventMessageListener {
-
private static final Topic KEYEVENT5_EXPIRED_TOPIC = new PatternTopic("__keyevent@*__:expired");
-
/**
-
* Creates new {@link MessageListener} for {@code __keyevent@*__:expired} messages.
-
*
-
* @param listenerContainer must not be {@literal null}.
-
*/
-
public KeyExpirationEvent5MessageListener(RedisMessageListenerContainer listenerContainer) {
-
super(listenerContainer);
-
}
-
@Override
-
public void doRegister(RedisMessageListenerContainer listenerContainer) {
-
listenerContainer.addMessageListener(this, KEYEVENT5_EXPIRED_TOPIC);
-
}
-
}
过期监听的管道默认是__keyevent@0__:expired,@后面的0表示第几个数据库,redis默认的数据库是0~15一共16个数据库,根据需求修改@后的数字。expired监听过期redis,可以换成*,监听所有。
配置bean:
-
@Bean
-
public RedisMessageListenerContainer container(JedisConnectionFactory jedisConnectionFactory, ApplicationContext context) {
-
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
-
container.setConnectionFactory(jedisConnectionFactory);
-
KeyExpirationEvent5MessageListener listener = new KeyExpirationEvent5MessageListener(container);
-
listener.doRegister(container);
-
listener.setApplicationEventPublisher(context);
-
return container;
-
}
监听:
-
@EventListener(classes = RedisKeyExpiredEvent.class)
-
@Override
-
public void event(RedisKeyExpiredEvent event) {
-
String expiredKey = new String(event.getSource());
-
System.out.println(expiredKey);
-
//expiredKey监听到的过期redis,根据业务要求进行操作
-
}
启动项目就可以监听redis了。