Java跨缓存调用流程统一

wen java案例 32

本文目录导读:

Java跨缓存调用流程统一

  1. 核心思想:面向接口 + 模板方法 + 多级路由
  2. 统一缓存抽象层
  3. 多级缓存实现(L1 + L2 架构)
  4. 跨缓存调用流程的统一调度器
  5. 统一监控与降级
  6. 最佳实践与配置
  7. 完整示例:业务层使用

针对Java跨缓存调用的流程统一,核心目标是屏蔽底层缓存差异(Redis、Caffeine、Memcached等),提供一致的编程接口,并灵活处理多级缓存调用链

以下是实现这一目标的标准化方案,涵盖了架构设计、统一抽象、多级缓存策略及最佳实践:

核心思想:面向接口 + 模板方法 + 多级路由


统一缓存抽象层

定义一个顶级接口,规范所有缓存操作,使业务代码不依赖具体缓存实现。

public interface UnifiedCache {
    // 核心操作
    <T> T get(String key, Class<T> type);
    <T> T get(String key, TypeReference<T> typeRef); // 支持泛型
    void set(String key, Object value, long ttl, TimeUnit unit);
    void delete(String key);
    boolean exists(String key);
    // 批量操作
    <T> Map<String, T> getMulti(Collection<String> keys, Class<T> type);
    void setMulti(Map<String, Object> keyValues, long ttl, TimeUnit unit);
}

多级缓存实现(L1 + L2 架构)

典型架构:本地缓存 (Caffeine) → 分布式缓存 (Redis),实现 UnifiedCache 接口,组合多个缓存层。

public class MultiLevelCache implements UnifiedCache {
    private final LocalCache localCache;   // Caffeine
    private final DistributedCache distCache; // Redis
    public MultiLevelCache(LocalCache localCache, DistributedCache distCache) {
        this.localCache = localCache;
        this.distCache = distCache;
    }
    @Override
    public <T> T get(String key, Class<T> type) {
        // 1. 尝试本地缓存
        T value = localCache.get(key, type);
        if (value != null) {
            return value;
        }
        // 2. 尝试分布式缓存
        value = distCache.get(key, type);
        if (value != null) {
            // 回填本地缓存(可根据情况设置较短TTL)
            localCache.set(key, value, 60, TimeUnit.SECONDS);
            return value;
        }
        return null;
    }
    @Override
    public void set(String key, Object value, long ttl, TimeUnit unit) {
        // 通常写策略:同时更新两级缓存(或延迟双删)
        distCache.set(key, value, ttl, unit);
        localCache.set(key, value, localTtlCalc(unit, ttl)); // 本地缓存TTL通常较短
    }
    @Override
    public void delete(String key) {
        // 删除策略:先删分布式,再删本地(避免并发读取时的不一致)
        distCache.delete(key);
        localCache.delete(key);
    }
}
// 使用时依赖注入 MultiLevelCache 即可

跨缓存调用流程的统一调度器

对于复杂的缓存调用链(如:查多个缓存源、聚合结果、异常降级),使用管道/过滤器模式责任链模式管理流程。

public interface CacheInvocationStep {
    <T> CacheResult<T> execute(CacheContext context);
}
// 流程编排示例
public class CacheInvocationPipeline {
    private List<CacheInvocationStep> steps;
    public CacheInvocationPipeline(List<CacheInvocationStep> steps) {
        this.steps = steps;
    }
    public <T> CacheResult<T> execute(String key, Class<T> type) {
        CacheContext ctx = new CacheContext(key, type);
        for (CacheInvocationStep step : steps) {
            CacheResult<T> result = step.execute(ctx);
            if (result.success()) {
                return result; // 命中则返回
            }
            // 未命中,传递给下一个步骤,结果可回填。
        }
        return CacheResult.miss(); // 全未命中,返回空
    }
}
// 典型步骤:Caffeine -> Redis -> Database -> 回填缓存

统一监控与降级

包装所有缓存调用,自动采集指标(命中率、耗时、异常),并支持动态降级。

public class MonitoredCache implements UnifiedCache {
    private final UnifiedCache delegate;
    private final MetricsCollector metrics;
    public <T> T get(String key, Class<T> type) {
        // 记录耗时、成功/失败、是否命中
        metrics.incrementCounter("cache.get.total");
        long start = System.nanoTime();
        try {
            T value = delegate.get(key, type);
            if (value != null) {
                metrics.incrementCounter("cache.get.hit");
            } else {
                metrics.incrementCounter("cache.get.miss");
            }
            return value;
        } catch (Exception e) {
            metrics.incrementCounter("cache.get.failure");
            // 可选降级:是否忽略异常返回null,或抛自定义异常
            return null; // 降级处理
        } finally {
            metrics.recordLatency("cache.get.latency", System.nanoTime() - start);
        }
    }
}

最佳实践与配置

关键配置项(集中管理,支持动态刷新):

# application.yml (示例)
unified.cache:
  layers:
    - type: caffeine
      max-size: 1000
      expire-after-write: 60s
      enabled: true
    - type: redis
      expire-after-write: 3600s
      enabled: true
    - type: redis-cluster # 可扩展更多缓存层
      enabled: false
  invocation:
    order: caffeine, redis # 调用顺序
    fail-fast: false # 是否因某一层失败而中断流程
    rollback-to-next: true # 某层失败后是否继续下一层

数据一致性策略(重要):

  • 强一致性要求:优先使用先更新数据库,再删除缓存(延迟双删),统一采用 delete 而非 update(能容忍短暂不一致)。
  • 最终一致性:接受短暂差异,使用 set 同时更新所有缓存层,并设置合理的TTL。
  • 跨地域同步:引入消息队列(如 Canal + MQ)监听数据库变更,广播清除缓存。

完整示例:业务层使用

@Service
public class UserService {
    @Autowired
    private UnifiedCache unifiedCache; // 注入统一缓存接口
    public User getUser(String userId) {
        // 调用统一接口,内部自动处理本地->远程->数据库->回填
        return unifiedCache.get("user:" + userId, User.class)
                .orElseGet(() -> loadFromDbAndCache(userId));
    }
    public void updateUser(User user) {
        // 先更新数据库
        userRepository.update(user);
        // 统一删除缓存(跨层自动处理)
        unifiedCache.delete("user:" + user.getId());
    }
}

Java跨缓存调用流程统一的精髓在于:

  1. 抽象隔离:通过 UnifiedCache 接口屏蔽实现细节。
  2. 层次组合:用 MultiLevelCache 实现本地+分布式缓存协同。
  3. 流程编排:用 Pipeline 模式管理调用顺序和降级。
  4. 非功能关注:统一监控、动态配置、一致性处理。

这样的设计下,业务代码几乎不需要修改即可切换底层缓存中间件,也无需关心多级缓存调用的复杂度。

抱歉,评论功能暂时关闭!