From 5d7fe1638e8e2e19b6cbf441a730ff48cc2cd1c4 Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Mon, 15 Dec 2025 18:24:58 +0800 Subject: [PATCH] =?UTF-8?q?feat(integration):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E9=99=8D=E7=BA=A7=E7=BC=93=E5=AD=98=E7=AD=96=E7=95=A5=EF=BC=8C?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E4=BC=98=E5=85=88=E4=BD=BF=E7=94=A81?= =?UTF-8?q?=E5=88=86=E9=92=9F=E5=86=85=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增优先缓存判断逻辑,1分钟内的缓存优先返回 - 调整默认缓存TTL常量命名以避免混淆 - 重构缓存读取流程,优先解析已读取的缓存值 - 提取缓存值解析方法,增强代码复用性 - 完善缓存存储与读取的日志记录 - 修复缓存TTL单位使用不一致的问题 --- .../service/IntegrationFallbackService.java | 74 +++++++++++++++++-- 1 file changed, 68 insertions(+), 6 deletions(-) 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 +}