You've already forked FrameTour-BE
feat(integration): 支持TypeReference泛型的降级缓存机制
- 在IntegrationFallbackService中新增支持TypeReference的executeWithFallback方法 - 新增getFallbackFromCache和parseFallbackCacheValue方法处理泛型缓存 - 更新DeviceStatusIntegrationService使用TypeReference保留泛型信息 - 更新RenderWorkerConfigIntegrationService使用TypeReference并修正缓存键 - 更新ScenicConfigIntegrationService使用TypeReference保留泛型信息 - 添加必要的Jackson TypeReference导入依赖
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package com.ycwl.basic.integration.common.service;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.ycwl.basic.integration.common.config.IntegrationProperties;
|
||||
import com.ycwl.basic.utils.JacksonUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -30,7 +31,7 @@ public class IntegrationFallbackService {
|
||||
|
||||
/**
|
||||
* 执行操作,失败时降级到缓存结果
|
||||
*
|
||||
*
|
||||
* @param serviceName 服务名称 (如: zt-device, zt-scenic)
|
||||
* @param cacheKey 缓存键
|
||||
* @param operation 主要操作
|
||||
@@ -78,6 +79,57 @@ public class IntegrationFallbackService {
|
||||
return fallbackResult;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行操作,失败时降级到缓存结果(支持TypeReference泛型)
|
||||
*
|
||||
* @param serviceName 服务名称 (如: zt-device, zt-scenic)
|
||||
* @param cacheKey 缓存键
|
||||
* @param operation 主要操作
|
||||
* @param typeReference 类型引用,用于保留泛型信息
|
||||
* @param <T> 结果类型
|
||||
* @return 操作结果或缓存的结果
|
||||
*/
|
||||
public <T> T executeWithFallback(String serviceName, String cacheKey, Supplier<T> operation, TypeReference<T> typeReference) {
|
||||
String fullKey = buildFullCacheKey(serviceName, cacheKey);
|
||||
String cachedValue = null;
|
||||
boolean isPreferredCache = false;
|
||||
try {
|
||||
cachedValue = redisTemplate.opsForValue().get(fullKey);
|
||||
isPreferredCache = cachedValue != null && isFallbackCachePreferred(serviceName, fullKey);
|
||||
} catch (Exception e) {
|
||||
log.warn("[{}] 读取降级缓存失败,将继续尝试远端获取, cacheKey: {}", serviceName, cacheKey, e);
|
||||
}
|
||||
|
||||
if (isPreferredCache) {
|
||||
T preferredCacheResult = parseFallbackCacheValue(serviceName, cacheKey, cachedValue, typeReference);
|
||||
if (preferredCacheResult != null) {
|
||||
log.debug("[{}] 命中优先缓存(<=1分钟),直接返回, cacheKey: {}", serviceName, cacheKey);
|
||||
return preferredCacheResult;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
T result = operation.get();
|
||||
if (result != null) {
|
||||
// 操作成功,保存结果用于将来的降级
|
||||
storeFallbackCache(serviceName, cacheKey, result);
|
||||
}
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
log.warn("[{}] 操作失败,尝试降级到缓存结果, cacheKey: {}", serviceName, cacheKey, e);
|
||||
T fallbackResult = parseFallbackCacheValue(serviceName, cacheKey, cachedValue, typeReference);
|
||||
if (fallbackResult == null) {
|
||||
fallbackResult = getFallbackFromCache(serviceName, cacheKey, typeReference);
|
||||
}
|
||||
if (fallbackResult == null) {
|
||||
log.error("[{}] 操作失败且无缓存数据, cacheKey: {}", serviceName, cacheKey);
|
||||
throw e;
|
||||
}
|
||||
log.info("[{}] 成功从降级缓存获取结果, cacheKey: {}", serviceName, cacheKey);
|
||||
return fallbackResult;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行操作,失败时降级到缓存结果,无返回值版本
|
||||
@@ -138,6 +190,23 @@ public class IntegrationFallbackService {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从降级缓存获取结果(支持TypeReference泛型)
|
||||
*/
|
||||
private <T> T getFallbackFromCache(String serviceName, String cacheKey, TypeReference<T> typeReference) {
|
||||
try {
|
||||
String fullKey = buildFullCacheKey(serviceName, cacheKey);
|
||||
String cachedValue = redisTemplate.opsForValue().get(fullKey);
|
||||
if (cachedValue != null) {
|
||||
log.debug("[{}] 从降级缓存获取结果, key: {}", serviceName, fullKey);
|
||||
return JacksonUtil.parseObject(cachedValue, typeReference);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("[{}] 从降级缓存获取结果失败, cacheKey: {}", serviceName, cacheKey, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前降级缓存是否应该优先使用。
|
||||
* 规则:缓存写入后的 1 分钟内优先使用,超过 1 分钟则优先尝试远端;远端失败再降级到缓存。
|
||||
@@ -177,6 +246,21 @@ public class IntegrationFallbackService {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析降级缓存值(支持TypeReference泛型)
|
||||
*/
|
||||
private <T> T parseFallbackCacheValue(String serviceName, String cacheKey, String cachedValue, TypeReference<T> typeReference) {
|
||||
if (cachedValue == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return JacksonUtil.parseObject(cachedValue, typeReference);
|
||||
} catch (Exception e) {
|
||||
log.warn("[{}] 解析降级缓存失败, cacheKey: {}", serviceName, cacheKey, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除降级缓存
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.ycwl.basic.integration.device.service;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.ycwl.basic.integration.common.exception.IntegrationException;
|
||||
import com.ycwl.basic.integration.common.response.CommonResponse;
|
||||
import com.ycwl.basic.integration.common.service.IntegrationFallbackService;
|
||||
@@ -49,6 +50,9 @@ public class DeviceStatusIntegrationService {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有在线设备(带降级,使用TypeReference保留泛型信息)
|
||||
*/
|
||||
public List<DeviceStatusDTO> getAllOnlineDevices() {
|
||||
log.debug("获取所有在线设备");
|
||||
return fallbackService.executeWithFallback(
|
||||
@@ -58,7 +62,7 @@ public class DeviceStatusIntegrationService {
|
||||
CommonResponse<List<DeviceStatusDTO>> response = deviceStatusClient.getAllOnlineDevices();
|
||||
return handleResponse(response, "获取所有在线设备失败");
|
||||
},
|
||||
List.class
|
||||
new TypeReference<List<DeviceStatusDTO>>() {}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.ycwl.basic.integration.render.service;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.ycwl.basic.integration.common.exception.IntegrationException;
|
||||
import com.ycwl.basic.integration.common.response.CommonResponse;
|
||||
import com.ycwl.basic.integration.common.service.IntegrationFallbackService;
|
||||
@@ -29,7 +30,7 @@ public class RenderWorkerConfigIntegrationService {
|
||||
private static final String SERVICE_NAME = "zt-render-worker";
|
||||
|
||||
/**
|
||||
* 获取工作器所有配置(带降级)
|
||||
* 获取工作器所有配置(带降级,使用TypeReference保留泛型信息)
|
||||
*/
|
||||
public List<RenderWorkerConfigV2DTO> getWorkerConfigs(Long workerId) {
|
||||
log.debug("获取渲染工作器配置列表, workerId: {}", workerId);
|
||||
@@ -37,12 +38,12 @@ public class RenderWorkerConfigIntegrationService {
|
||||
SERVICE_NAME,
|
||||
"worker:configs:" + workerId,
|
||||
() -> {
|
||||
CommonResponse<List<RenderWorkerConfigV2DTO>> response =
|
||||
CommonResponse<List<RenderWorkerConfigV2DTO>> response =
|
||||
renderWorkerConfigV2Client.getWorkerConfigs(workerId);
|
||||
List<RenderWorkerConfigV2DTO> configs = handleResponse(response, "获取渲染工作器配置列表失败");
|
||||
return configs != null ? configs : Collections.emptyList();
|
||||
},
|
||||
List.class
|
||||
new TypeReference<List<RenderWorkerConfigV2DTO>>() {}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -70,12 +71,12 @@ public class RenderWorkerConfigIntegrationService {
|
||||
log.debug("获取渲染工作器平铺配置, workerId: {}", workerId);
|
||||
return fallbackService.executeWithFallback(
|
||||
SERVICE_NAME,
|
||||
"worker:config:" + workerId,
|
||||
"worker:flat:config:" + workerId,
|
||||
() -> {
|
||||
List<RenderWorkerConfigV2DTO> configs = getWorkerConfigsInternal(workerId);
|
||||
return flattenConfigs(configs);
|
||||
},
|
||||
Map.class
|
||||
new TypeReference<Map<String, Object>>() {}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.ycwl.basic.integration.scenic.service;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.ycwl.basic.integration.common.exception.IntegrationException;
|
||||
import com.ycwl.basic.integration.common.response.CommonResponse;
|
||||
import com.ycwl.basic.integration.common.service.IntegrationFallbackService;
|
||||
@@ -22,6 +23,9 @@ public class ScenicConfigIntegrationService {
|
||||
|
||||
private static final String SERVICE_NAME = "zt-scenic";
|
||||
|
||||
/**
|
||||
* 获取景区配置列表(带降级,使用TypeReference保留泛型信息)
|
||||
*/
|
||||
public List<ScenicConfigV2DTO> listConfigs(Long scenicId) {
|
||||
log.debug("获取景区配置列表, scenicId: {}", scenicId);
|
||||
return fallbackService.executeWithFallback(
|
||||
@@ -31,7 +35,7 @@ public class ScenicConfigIntegrationService {
|
||||
CommonResponse<List<ScenicConfigV2DTO>> response = scenicConfigV2Client.listConfigs(scenicId);
|
||||
return handleResponse(response, "获取景区配置列表失败");
|
||||
},
|
||||
List.class
|
||||
new TypeReference<List<ScenicConfigV2DTO>>() {}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user