Переглянути джерело

gemini车队列表写入缓存,减少请求次数

chenbiao 5 місяців тому
батько
коміт
f0e1bda3ef

+ 4 - 1
netflix-dao/src/main/java/com/cyksj/model/views/GeminiCarInfoView.java

@@ -2,6 +2,7 @@ package com.cyksj.model.views;
 
 import lombok.Data;
 
+import java.io.Serializable;
 import java.util.Date;
 
 /**
@@ -11,7 +12,9 @@ import java.util.Date;
  * @date 2025/1/4
  */
 @Data
-public class GeminiCarInfoView {
+public class GeminiCarInfoView implements Serializable {
+
+    private static final long serialVersionUID = 1L;
 
     /**
      * 车次id

+ 3 - 0
netflix-service/src/main/java/com/cyksj/redis/RedisService.java

@@ -862,6 +862,9 @@ public class RedisService {
         CLAUDE_CODE_TY_DAY_CARD_KEY("claude_code_ty_day_card_key:", "claude_code体验天卡key", 30L),
         NANO_TY_DAY_CARD_KEY("nano_ty_day_card_key:", "nano体验天卡key", 30L),
         DUP_GOODS_ACCOUNT_KEY("dup_goods_account_key:%s:%s", "平台账号去重key", 60 * 5L),
+        GEMINI_CAR_LIST_CACHE("gemini:car:list:%s", "gemini车队列表缓存", 15 * 60L),
+        GEMINI_CAR_LIST_EMPTY_CACHE("gemini:car:list:%s", "gemini车队列表空值缓存", 5L),
+        GEMINI_CAR_LIST_LOCK("gemini:car:list:lock:%s", "gemini车队列表锁", 60L),
         ;
 
         private String name;

+ 58 - 3
netflix-service/src/main/java/com/cyksj/service/gemini/impl/GeminiServiceImpl.java

@@ -292,7 +292,64 @@ public class GeminiServiceImpl implements GeminiService {
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public SearchResult<GeminiCarInfoView> getCarInfoList(String domain, int page, int size) {
+        RedisService.key cacheEnum = RedisService.key.GEMINI_CAR_LIST_CACHE;
+        RedisService.key lockEnum = RedisService.key.GEMINI_CAR_LIST_LOCK;
+        String cacheKey = cacheEnum.getNameFormat(domain);
+        String lockKey = lockEnum.getNameFormat(domain);
+
+        // 1. 先查缓存
+        Object cached = redisService.get(cacheKey);
+        if (cached != null) {
+            List<GeminiCarInfoView> cachedList = (List<GeminiCarInfoView>) cached;
+            SearchResult<GeminiCarInfoView> result = new SearchResult<>(cachedList);
+            result.setTotalCount(cachedList.size());
+            return result;
+        }
+
+        // 2. 缓存不存在,尝试获取锁,单线程去拉取
+        boolean locked = redisService.setNx(lockKey, "1", lockEnum.getTimeout());
+        if (!locked) {
+            // 没拿到锁,说明其他线程正在拉取,返回空列表
+            SearchResult<GeminiCarInfoView> result = new SearchResult<>(new ArrayList<>());
+            result.setTotalCount(0);
+            return result;
+        }
+
+        try {
+            // 双重检查,拿到锁后再查一次缓存
+            cached = redisService.get(cacheKey);
+            if (cached != null) {
+                List<GeminiCarInfoView> cachedList = (List<GeminiCarInfoView>) cached;
+                SearchResult<GeminiCarInfoView> result = new SearchResult<>(cachedList);
+                result.setTotalCount(cachedList.size());
+                return result;
+            }
+
+            // 3. 真正去请求数据
+            List<GeminiCarInfoView> carInfoList = fetchCarInfoListFromRemote(domain, page, size);
+
+            // 4. 存入缓存
+            if (carInfoList.isEmpty()) {
+                // 空值也缓存,防穿透,缓存5秒
+                redisService.set(cacheKey, carInfoList, RedisService.key.GEMINI_CAR_LIST_EMPTY_CACHE.getTimeout());
+            } else {
+                redisService.set(cacheKey, carInfoList, cacheEnum.getTimeout());
+            }
+
+            SearchResult<GeminiCarInfoView> result = new SearchResult<>(carInfoList);
+            result.setTotalCount(carInfoList.size());
+            return result;
+        } finally {
+            redisService.del(lockKey);
+        }
+    }
+
+    /**
+     * 从远程接口拉取车队列表(carpage + status)
+     */
+    private List<GeminiCarInfoView> fetchCarInfoListFromRemote(String domain, int page, int size) {
         GeminiCarPageResponse carPageResponse = getCarPage(domain, page, size);
 
         List<GeminiCarInfoView> carInfoList = new ArrayList<>();
@@ -331,9 +388,7 @@ public class GeminiServiceImpl implements GeminiService {
         // 按score从低到高排序
         carInfoList.sort(Comparator.comparingDouble(c -> c.getScore() != null ? c.getScore() : 0.0));
 
-        SearchResult<GeminiCarInfoView> result = new SearchResult<>(carInfoList);
-        result.setTotalCount(carInfoList.size());
-        return result;
+        return carInfoList;
     }
 
     @Override