Explorar o código

增加redis监听排行榜信息时效
获取排行榜信息时判断失效时间小于2分钟则重新查询设置续期

marxjaw hai 3 meses
pai
achega
e23ad57ecb

+ 29 - 0
yt-middle/middle-platform/src/main/java/com/ytpm/middle/config/redis/RedisListenerConfig.java

@@ -0,0 +1,29 @@
+package com.ytpm.middle.config.redis;
+
+import com.ytpm.middle.monitor.RedisKeyExpirationListener;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
+import org.springframework.data.redis.listener.RedisMessageListenerContainer;
+
+/**
+ * redis 监听器配置
+ * @author marx
+ * @date 2025/7/29 16:09
+ */
+@Configuration
+public class RedisListenerConfig {
+
+    @Bean
+    RedisMessageListenerContainer listenerContainer(RedisConnectionFactory connectionFactory) {
+        RedisMessageListenerContainer listenerContainer = new RedisMessageListenerContainer();
+        listenerContainer.setConnectionFactory(connectionFactory);
+        return listenerContainer;
+    }
+
+    @Bean
+    KeyExpirationEventMessageListener redisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
+        return new RedisKeyExpirationListener(listenerContainer);
+    }
+}

+ 85 - 0
yt-middle/middle-platform/src/main/java/com/ytpm/middle/monitor/RedisKeyExpirationListener.java

@@ -0,0 +1,85 @@
+package com.ytpm.middle.monitor;
+
+import com.alibaba.fastjson.JSON;
+import com.ytpm.agent.view.AgentAppView;
+import com.ytpm.feign.AppFeign;
+import com.ytpm.middle.dao.ApkMapper;
+import com.ytpm.middle.util.RedisUtil;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import com.ytpm.middle.view.AppRankingListVO;
+import com.ytpm.middle.view.DashboardRankingListVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.redis.connection.Message;
+import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
+import org.springframework.data.redis.listener.RedisMessageListenerContainer;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+/**
+ * redis 监听器
+ */
+@Slf4j
+@Component
+public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
+ 
+
+    @Resource
+    RedisUtil redisUtil ;
+    @Resource
+    ApkMapper apkMapper;
+    @Resource
+    AppFeign appFeign;
+    @Value("${ranking.expire}")
+    private long rankingExpire;
+    @Value("${ranking.limit}")
+    private int rankingLimit;
+    private static final String RANKING_KEY = "yt_ranking";
+ 
+    /**
+     * Creates new {@link } for {@code __keyevent@*__:expired} messages.
+     *
+     * @param listenerContainer must not be {@literal null}.
+     */
+    public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
+        super(listenerContainer);
+    }
+ 
+    /**
+     * 监听redis过期的 key 进行处理
+     */
+    @Override
+    public void onMessage(Message message, byte[] pattern) {
+        String key = String.valueOf(message);
+        System.err.println("发现过期的key:"+key);
+        if("yt_ranking3".equals(key)){
+             getRankingAnCache(3);
+        }
+        if("yt_ranking2".equals(key)){
+            getRankingAnCache(2);
+        }
+        if("yt_ranking1".equals(key)){
+            getRankingAnCache(1);
+        }
+    }
+
+    /**
+     * 查询排行榜并缓存
+     */
+    private void getRankingAnCache(Integer sortBy) {
+        DashboardRankingListVO rankingVO = appFeign.queryRankingList(sortBy,rankingLimit);
+        List<AppRankingListVO> appRankingList = rankingVO.getAppRankingList();
+        List<AgentAppView> views = apkMapper.queryAll();
+        Map<String, String> collect = views.stream().collect(Collectors.toMap(AgentAppView::getAppId, AgentAppView::getAppName));
+        for (AppRankingListVO vo : appRankingList) {
+            vo.setAppName(collect.get(vo.getAppId()));
+        }
+        rankingVO.setAppRankingList(appRankingList);
+        redisUtil.setTimeOutMinutesStr(RANKING_KEY+sortBy, JSON.toJSONString(rankingVO),rankingExpire);
+    }
+}

+ 14 - 3
yt-middle/middle-platform/src/main/java/com/ytpm/middle/service/impl/CountServiceImpl.java

@@ -34,7 +34,7 @@ public class CountServiceImpl implements CountService {
     @Resource
     private RedisUtil redisUtil;
     @Value("${ranking.expire}")
-    private int rankingExpire;
+    private long rankingExpire;
     @Value("${ranking.limit}")
     private int rankingLimit;
     private static final String RANKING_KEY = "yt_ranking";
@@ -64,18 +64,29 @@ public class CountServiceImpl implements CountService {
         //判断redis中是否存在排行榜信息 不存在则查询数据进行更新,存在则直接取出
         if(Boolean.TRUE.equals(redisUtil.hasKey(RANKING_KEY+sortBy))){
             String ranking = redisUtil.getStr(RANKING_KEY+sortBy);
+            long expire = redisUtil.getExpire(RANKING_KEY + sortBy);
+            if(Math.subtractExact(rankingExpire,expire)<2){
+                getRankingAnCache(sortBy);
+            }
             return Result.resultObjOk(JSON.parseObject(ranking, DashboardRankingListVO.class));
         }
+        return Result.resultObjOk(getRankingAnCache(sortBy));
+    }
+
+    /**
+     * 查询排行榜并缓存
+     */
+    private DashboardRankingListVO getRankingAnCache(Integer sortBy) {
         DashboardRankingListVO rankingVO = appFeign.queryRankingList(sortBy,rankingLimit);
         List<AppRankingListVO> appRankingList = rankingVO.getAppRankingList();
         List<AgentAppView> views = apkMapper.queryAll();
-        Map<String, String> collect = views.stream().collect(Collectors.toMap(AgentAppView::getAppId, o -> o.getAppName()));
+        Map<String, String> collect = views.stream().collect(Collectors.toMap(AgentAppView::getAppId, AgentAppView::getAppName));
         for (AppRankingListVO vo : appRankingList) {
             vo.setAppName(collect.get(vo.getAppId()));
         }
         rankingVO.setAppRankingList(appRankingList);
         redisUtil.setTimeOutMinutesStr(RANKING_KEY+sortBy, JSON.toJSONString(rankingVO),rankingExpire);
-        return Result.resultObjOk(rankingVO);
+        return rankingVO;
     }
 
     /**

+ 8 - 0
yt-middle/middle-platform/src/main/java/com/ytpm/middle/util/RedisUtil.java

@@ -39,6 +39,14 @@ public class RedisUtil {
     @Resource(name = "redisTemplate")
     ValueOperations<Object, Object> valOpsObj;
 
+    /**
+     * 查询并获取key的有效时间
+     */
+    public Long getExpire(String key) {
+       return valOpsObj.getOperations().getExpire(key, TimeUnit.MINUTES);
+    }
+
+
     /**
      * 根据指定key获取String
      * @param key