无需设置TTL,如何按固定间隔刷新Caffeine缓存?
使用Caffeine实现定时缓存刷新
你可以通过Caffeine的refreshAfterWrite配置结合调度器,或者主动触发缓存刷新的方式,实现每15分钟执行loadData的需求,不需要依赖@Scheduled注解,具体方案如下:
方案1:基于缓存项生命周期的自动刷新
这种方式让每个缓存项在写入/刷新后的15分钟自动触发异步刷新,适合不需要全局统一刷新时间的场景:
// 创建调度器,用于异步执行刷新任务 ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); Cache<String, String> cache = Caffeine.newBuilder() // 设置写入后15分钟触发刷新 .refreshAfterWrite(15, TimeUnit.MINUTES) // 指定调度器,让刷新任务在异步线程执行 .scheduler(Scheduler.forScheduledExecutorService(scheduler)) // 绑定数据加载方法 .build(this::loadData);
关键说明:
refreshAfterWrite定义了缓存项的刷新间隔,每个缓存项会独立按照自己的写入时间触发刷新,不是全局统一批量刷新。scheduler()的作用是把刷新任务从业务线程转移到指定的异步线程池,避免阻塞请求,默认情况下刷新任务会在访问缓存的线程中执行。
方案2:全局批量定时刷新所有缓存项
如果需要每15分钟统一刷新所有缓存中的key,可以主动遍历缓存key并调用refresh方法,配合Caffeine的调度器实现:
// 初始化缓存 Cache<String, String> cache = Caffeine.newBuilder() .build(this::loadData); // 获取缓存的key集合视图 ConcurrentMap<String, String> cacheEntries = cache.asMap(); // 使用Caffeine提供的系统调度器,定时执行批量刷新 Scheduler scheduler = Scheduler.systemScheduler(); scheduler.scheduleAtFixedRate(() -> { // 遍历所有key,强制触发刷新 cacheEntries.keySet().forEach(cache::refresh); }, 0, 15, TimeUnit.MINUTES);
关键说明:
cache.refresh(key)会异步调用loadData(key)更新缓存,无论缓存项是否过期都会执行刷新。Scheduler.systemScheduler()是Caffeine封装的系统默认调度器,也可以自定义ScheduledExecutorService传入,实现线程池的自定义配置。
关于Caffeine scheduler()方法的补充
scheduler()本身不提供定时触发的能力,它的核心作用是指定执行缓存刷新/加载任务的异步线程池,避免刷新逻辑阻塞业务线程。定时刷新的逻辑还是需要通过refreshAfterWrite(基于缓存项生命周期)或者主动调用refresh(批量定时)来触发。
内容的提问来源于stack exchange,提问作者Rupesh
相关产品推荐
相关产品推荐

