RedisKey的失效監(jiān)聽(tīng)器KeyExpirationEventMessageListener問(wèn)題
RedisKey的失效監(jiān)聽(tīng)器KeyExpirationEventMessageListener
利用KeyExpirationEventMessageListener實(shí)現(xiàn)redis的key失效監(jiān)聽(tīng)。
在使用redis時(shí),所有的key都要設(shè)置過(guò)期時(shí)間,過(guò)期之后,redis就會(huì)把對(duì)應(yīng)的key清除掉。
此方法可以監(jiān)聽(tīng)redis的key失效,在失效時(shí)做一些邏輯處理。話不多說(shuō),上代碼。
依賴(lài)
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
實(shí)現(xiàn)
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) { // 只監(jiān)聽(tīng)指定redis數(shù)據(jù)庫(kù)的key過(guò)期事件 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" // 觸發(fā)key失效發(fā)布的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(); } } }
監(jiān)聽(tīng)處理類(lèi)
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存儲(chǔ)所有實(shí)現(xiàn)Strategy接口的Bean * key:beanName * value:實(shí)現(xiàn)Strategy接口Bean */ private final Map<String, PushMessageStrategy> strategyMap = Maps.newConcurrentMap(); /** * 注入所有實(shí)現(xiàn)了Strategy接口的Bean * * @param strategyMap the strategy map */ @Autowired public PushMessageStrategyContext(Map<String, PushMessageStrategy> strategyMap) { strategyMap.forEach(this.strategyMap::put); } /** * 策略監(jiān)聽(tīng)redis所有過(guò)期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("找不到對(duì)應(yīng)的策略:{}", strategyMap.get(beanName)); } } }
public interface PushMessageStrategy { void handleRedisExpireKey(String redisInvalidKey); }
大家在使用的時(shí)候,可以針對(duì)自己不同的場(chǎng)景,實(shí)現(xiàn)PushMessageStrategy 接口,重寫(xiě)handleRedisExpireKey方法。
在方法中處理不同的邏輯。
首先,在redis’中有key失效過(guò)期時(shí),AgentOrderRedisKeyExpiredListener 監(jiān)聽(tīng)到redis實(shí)現(xiàn),會(huì)執(zhí)行doHandleMessage方法,方法中會(huì)調(diào)用PushMessageStrategyContext 的獲取不同策略的Bean,進(jìn)行業(yè)務(wù)操作。
至此,監(jiān)聽(tīng)redis中key失效完成。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java reservedcodecachesize虛擬機(jī)參數(shù)案例詳解
這篇文章主要介紹了Java reservedcodecachesize虛擬機(jī)參數(shù)案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08idea2019.1.4 鼠標(biāo)放到方法上顯示注解的實(shí)現(xiàn)操作
這篇文章主要介紹了idea2019.1.4 鼠標(biāo)放到方法上顯示注解的實(shí)現(xiàn)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-02-02springboot項(xiàng)目接入第三方qq郵箱驗(yàn)證登錄的全過(guò)程
互聯(lián)網(wǎng)發(fā)展到現(xiàn)在,相必大家都知道發(fā)送郵件應(yīng)該是網(wǎng)站的必備功能之一,下面這篇文章主要給大家介紹了關(guān)于springboot項(xiàng)目接入第三方qq郵箱驗(yàn)證登錄的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-04-04Spring Boot 自定義 Shiro 過(guò)濾器無(wú)法使用 @Autowired問(wèn)題及解決方法
這篇文章主要介紹了Spring Boot 自定義 Shiro 過(guò)濾器無(wú)法使用 @Autowired問(wèn)題及解決方法 ,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-06-06SpringBoot快速設(shè)置攔截器并實(shí)現(xiàn)權(quán)限驗(yàn)證的方法
本篇文章主要介紹了SpringBoot快速設(shè)置攔截器并實(shí)現(xiàn)權(quán)限驗(yàn)證的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-01-01解決FeignClient發(fā)送post請(qǐng)求異常的問(wèn)題
這篇文章主要介紹了FeignClient發(fā)送post請(qǐng)求異常的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07Alibaba?SpringCloud集成Nacos、openFeign實(shí)現(xiàn)負(fù)載均衡的解決方案
Spring?Cloud?Alibaba?致力于提供微服務(wù)開(kāi)發(fā)的一站式解決方案,此項(xiàng)目包含開(kāi)發(fā)分布式應(yīng)用微服務(wù)的必需組件,這篇文章主要介紹了Alibaba?SpringCloud集成Nacos、openFeign實(shí)現(xiàn)負(fù)載均衡,需要的朋友可以參考下2024-05-05Java使用ffmpeg和mencoder實(shí)現(xiàn)視頻轉(zhuǎn)碼
這篇文章主要為大家詳細(xì)介紹了Java使用ffmpeg和mencoder實(shí)現(xiàn)視頻轉(zhuǎn)碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12