RedisKey的失效监听器KeyExpirationEventMessageListener问题
作者:是小故事呀
这篇文章主要介绍了RedisKey的失效监听器KeyExpirationEventMessageListener问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
RedisKey的失效监听器KeyExpirationEventMessageListener
利用KeyExpirationEventMessageListener实现redis的key失效监听。
在使用redis时,所有的key都要设置过期时间,过期之后,redis就会把对应的key清除掉。
此方法可以监听redis的key失效,在失效时做一些逻辑处理。话不多说,上代码。
依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
实现
import com.upbim.twin.park.common.constans.Constants; import com.upbim.twin.park.server.strategy.PushMessageStrategyContext; import lombok.extern.slf4j.Slf4j; import org.slf4j.MDC; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.data.redis.RedisProperties; import org.springframework.data.redis.connection.Message; 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; import org.springframework.stereotype.Service; import java.util.UUID; import static com.upbim.twin.park.common.constans.Constants.TRACE_ID; @Slf4j @Service public class AgentOrderRedisKeyExpiredListener extends KeyExpirationEventMessageListener { @Autowired private PushMessageStrategyContext pushMessageStrategyContext; @Autowired private RedisProperties redisProperties; /** * Creates new MessageListener for {@code __keyevent@*__:expired} messages. * * @param listenerContainer must not be {@literal null}. */ public AgentOrderRedisKeyExpiredListener(RedisMessageListenerContainer listenerContainer) { super(listenerContainer); } @Override protected void doRegister(RedisMessageListenerContainer listenerContainer) { // 只监听指定redis数据库的key过期事件 Topic topic = new PatternTopic(String.format("__keyevent@%s__:expired", redisProperties.getDatabase())); listenerContainer.addMessageListener(this, topic); } @Override protected void doHandleMessage(Message message) { // 订阅的topic: new String(message.getChannel(), UTF_8) ---> "__keyevent@0__:expired" // 触发key失效发布的key:new String(message.getBody(), UTF_8) ---> "demoKey" MDC.put(TRACE_ID, UUID.randomUUID().toString()); try { log.info(String.format("Redis key expired event:%s", message.toString())); String beanName = message.toString().split(Constants.COLON)[Constants.ONE]; pushMessageStrategyContext.handleRedisExpireKey(beanName, message.toString()); super.doHandleMessage(message); } finally { MDC.clear(); } } }
监听处理类
package com.upbim.twin.park.server.strategy; import com.google.common.collect.Maps; import com.upbim.twin.park.server.strategy.nozzle.PushMessageStrategy; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.Map; import java.util.Objects; @Slf4j @Component public class PushMessageStrategyContext { /** * 使用线程安全的ConcurrentHashMap存储所有实现Strategy接口的Bean * key:beanName * value:实现Strategy接口Bean */ private final Map<String, PushMessageStrategy> strategyMap = Maps.newConcurrentMap(); /** * 注入所有实现了Strategy接口的Bean * * @param strategyMap the strategy map */ @Autowired public PushMessageStrategyContext(Map<String, PushMessageStrategy> strategyMap) { strategyMap.forEach(this.strategyMap::put); } /** * 策略监听redis所有过期key * * @param beanName the bean name * @param redisInvalidKey the redis invalid key * @return */ public void handleRedisExpireKey(String beanName, String redisInvalidKey) { if (Objects.nonNull(strategyMap.get(beanName))) { strategyMap.get(beanName).handleRedisExpireKey(redisInvalidKey); } else { log.warn("找不到对应的策略:{}", strategyMap.get(beanName)); } } }
public interface PushMessageStrategy { void handleRedisExpireKey(String redisInvalidKey); }
大家在使用的时候,可以针对自己不同的场景,实现PushMessageStrategy 接口,重写handleRedisExpireKey方法。
在方法中处理不同的逻辑。
首先,在redis’中有key失效过期时,AgentOrderRedisKeyExpiredListener 监听到redis实现,会执行doHandleMessage方法,方法中会调用PushMessageStrategyContext 的获取不同策略的Bean,进行业务操作。
至此,监听redis中key失效完成。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。