diff --git a/src/main/java/com/ycwl/basic/integration/common/service/IntegrationFallbackService.java b/src/main/java/com/ycwl/basic/integration/common/service/IntegrationFallbackService.java index ca3a9cd4..d5b51520 100644 --- a/src/main/java/com/ycwl/basic/integration/common/service/IntegrationFallbackService.java +++ b/src/main/java/com/ycwl/basic/integration/common/service/IntegrationFallbackService.java @@ -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 executeWithFallback(String serviceName, String cacheKey, Supplier operation, Class 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 parseFallbackCacheValue(String serviceName, String cacheKey, String cachedValue, Class 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; } -} \ No newline at end of file +}