|
@@ -292,7 +292,64 @@ public class GeminiServiceImpl implements GeminiService {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
public SearchResult<GeminiCarInfoView> getCarInfoList(String domain, int page, int size) {
|
|
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);
|
|
GeminiCarPageResponse carPageResponse = getCarPage(domain, page, size);
|
|
|
|
|
|
|
|
List<GeminiCarInfoView> carInfoList = new ArrayList<>();
|
|
List<GeminiCarInfoView> carInfoList = new ArrayList<>();
|
|
@@ -331,9 +388,7 @@ public class GeminiServiceImpl implements GeminiService {
|
|
|
// 按score从低到高排序
|
|
// 按score从低到高排序
|
|
|
carInfoList.sort(Comparator.comparingDouble(c -> c.getScore() != null ? c.getScore() : 0.0));
|
|
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
|
|
@Override
|