feat(integration): 优化降级缓存策略,支持优先使用1分钟内缓存

- 新增优先缓存判断逻辑,1分钟内的缓存优先返回
- 调整默认缓存TTL常量命名以避免混淆
- 重构缓存读取流程,优先解析已读取的缓存值
- 提取缓存值解析方法,增强代码复用性
- 完善缓存存储与读取的日志记录
- 修复缓存TTL单位使用不一致的问题
This commit is contained in:
2025-12-15 18:24:58 +08:00
parent c0f07ee9f4
commit 5d7fe1638e

View File

@@ -25,7 +25,8 @@ public class IntegrationFallbackService {
// 默认降级缓存配置
private static final String DEFAULT_FALLBACK_PREFIX = "integration:fallback:";
private static final long DEFAULT_FALLBACK_TTL = 7; // 7天
private static final long DEFAULT_FALLBACK_TTL_DAYS = 1; // 7天
private static final long FALLBACK_CACHE_PREFERRED_MAX_AGE_SECONDS = 60; // 1分钟
/**
* 执行操作,失败时降级到缓存结果
@@ -38,6 +39,24 @@ public class IntegrationFallbackService {
* @return 操作结果或缓存的结果
*/
public <T> T executeWithFallback(String serviceName, String cacheKey, Supplier<T> operation, Class<T> resultClass) {
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, resultClass);
if (preferredCacheResult != null) {
log.debug("[{}] 命中优先缓存(<=1分钟),直接返回, cacheKey: {}", serviceName, cacheKey);
return preferredCacheResult;
}
}
try {
T result = operation.get();
if (result != null) {
@@ -47,7 +66,10 @@ public class IntegrationFallbackService {
return result;
} catch (Exception e) {
log.warn("[{}] 操作失败,尝试降级到缓存结果, cacheKey: {}", serviceName, cacheKey, e);
T fallbackResult = getFallbackFromCache(serviceName, cacheKey, resultClass);
T fallbackResult = parseFallbackCacheValue(serviceName, cacheKey, cachedValue, resultClass);
if (fallbackResult == null) {
fallbackResult = getFallbackFromCache(serviceName, cacheKey, resultClass);
}
if (fallbackResult == null) {
log.error("[{}] 操作失败且无缓存数据, cacheKey: {}", serviceName, cacheKey);
throw e;
@@ -88,8 +110,8 @@ public class IntegrationFallbackService {
try {
String fullKey = buildFullCacheKey(serviceName, cacheKey);
String jsonValue = JacksonUtil.toJSONString(value);
long ttl = getFallbackTtl(serviceName);
redisTemplate.opsForValue().set(fullKey, jsonValue, ttl, TimeUnit.DAYS);
long ttlDays = getFallbackTtl(serviceName);
redisTemplate.opsForValue().set(fullKey, jsonValue, ttlDays, TimeUnit.DAYS);
log.debug("[{}] 存储降级缓存成功, key: {}", serviceName, fullKey);
} catch (Exception e) {
log.warn("[{}] 存储降级缓存失败, cacheKey: {}", serviceName, cacheKey, e);
@@ -115,6 +137,46 @@ public class IntegrationFallbackService {
}
return null;
}
/**
* 判断当前降级缓存是否应该优先使用。
* 规则:缓存写入后的 1 分钟内优先使用,超过 1 分钟则优先尝试远端;远端失败再降级到缓存。
*/
private boolean isFallbackCachePreferred(String serviceName, String fullKey) {
try {
Long remainingSeconds = redisTemplate.getExpire(fullKey, TimeUnit.SECONDS);
if (remainingSeconds == null || remainingSeconds < 0) {
return false;
}
long ttlDays = getFallbackTtl(serviceName);
long expectedTtlSeconds = TimeUnit.DAYS.toSeconds(ttlDays);
if (remainingSeconds > expectedTtlSeconds) {
return false;
}
long ageSeconds = expectedTtlSeconds - remainingSeconds;
return ageSeconds <= FALLBACK_CACHE_PREFERRED_MAX_AGE_SECONDS;
} catch (Exception e) {
log.warn("[{}] 判断降级缓存有效期失败,视为不优先, key: {}", serviceName, fullKey, e);
return false;
}
}
private <T> T parseFallbackCacheValue(String serviceName, String cacheKey, String cachedValue, Class<T> resultClass) {
if (cachedValue == null) {
return null;
}
try {
if (resultClass == String.class) {
return resultClass.cast(cachedValue);
}
return JacksonUtil.parseObject(cachedValue, resultClass);
} catch (Exception e) {
log.warn("[{}] 解析降级缓存失败, cacheKey: {}", serviceName, cacheKey, e);
return null;
}
}
/**
* 清除降级缓存
@@ -204,7 +266,7 @@ public class IntegrationFallbackService {
*/
private long getFallbackTtl(String serviceName) {
if (!integrationProperties.getFallback().isEnabled()) {
return DEFAULT_FALLBACK_TTL;
return DEFAULT_FALLBACK_TTL_DAYS;
}
// 获取服务特定的TTL
@@ -254,4 +316,4 @@ public class IntegrationFallbackService {
private String cacheKeyPattern;
private long fallbackTtlDays;
}
}
}