是否可以将 Guava Cache(或其他库)行为配置为:如果需要重新加载,return 先前的条目,在后台重新加载(参见规范)

Is it possible to configure Guava Cache (or other library) behaviour to be: If time to reload, return previous entry, reload in background (see specs)

我想要一个像这样工作的缓存:

(重新加载失败后(案例 E),下一个请求按照案例 C 处理。)

(如果case A以Exception结束,则抛出Exception)

有谁知道现有的实现,还是我必须自己实现?

cache2k 中,我完全实现了您上面描述的行为。以下是使用这些功能构建缓存的方法:

  CacheBuilder.newCache(Key.class, Value.class)
    .name("myCache")
    .source(new YourSourceImplementation())
    .backgroundRefresh(true)
    .suppressExceptions(true)
    .maxSize(7777) // maximum entries in the cache
    .expiryDuration(60, TimeUnit.SECONDS)
    .exceptionExpiryDuration(15, TimeUnit.SECONDS)
    .build();

exipryDuration 是值在 war 插入或修改后被视为有效的持续时间。 exceptionExpiryDuration的单独设置是发生异常后尝试下一次刷新的时间。

如果发生异常,但没有有效条目,异常会被缓存并重新抛出 exceptionExpiryDuration 次。

您还可以动态计算到期时间,例如基于异常类型。更多信息在博客条目 About caching exceptions

使用 backgroundRefresh 条目在过期后刷新。当在有效期内刷新后没有访问时,条目将不再刷新并最终被驱逐。

不幸的是,我在正确记录所有这些有用的功能方面确实落后了。如果您有任何问题,可以使用标签 cache2k。如果您喜欢一些改进,请在 GitHub.

上提出问题

该代码在我们的生产应用程序中运行良好已有大约一年了。实际上,suppressExceptions 始终是默认值。它很有帮助,例如如果出现短暂的网络中断。

顺便说一句:同时,我将这些语义归入术语缓存弹性

https://github.com/ben-manes/caffeine

Caffeine 使用 refreshAfterWrite:

提供了我想要开箱即用的行为
LoadingCache<K, V> cache = Caffeine.newBuilder()
   .refreshAfterWrite(expireTime, timeUnit)
   .maximumSize(maxCountOfItems)
   .build(k->loader.load(k));