Guava 11:缓存无法使用 5 分钟刷新

Guava 11: Cache not working with 5 minute refresh

我们在每 30 秒运行一次的 HeartBeat 线程中使用以下方法,我们为 ClientsDAO.getClients() 引入了 5 分钟刷新一次的 Guava 缓存,这样我们就不会每 30 秒访问一次数据库秒。

private List<String> getClients() {
        final Supplier<List<String>> supplier = () ->  ClientsDAO.getClients();
        if(Server.CACHE_REFRESH_DURATION <=0)
            return supplier.get();
        else{
        LOG.debug("Fetching Clients from cache, duration = "+Server.CACHE_REFRESH_DURATION+". timeunit = "+Server.CACHE_REFRESH_TIMEUNIT);  
        return Suppliers.memoizeWithExpiration(supplier, Server.CACHE_REFRESH_DURATION, Server.CACHE_REFRESH_TIMEUNIT).get();
        }       
    }

正如您在下面的日志中看到的那样,每次线程 HeartBeat 运行时它都会访问数据库而不是从缓存中获取它。有人可以帮我解决吗?

[Jun 10 10:16:05] pool-16-thread-1 | DEBUG | com.server.Heartbeat | Fetching Clients from cache, duration = 5. timeunit = MINUTES
[Jun 10 10:16:05] pool-16-thread-1 | DEBUG | com.server.ClientsDAO | Getting DB connection
[Jun 10 10:16:05] pool-16-thread-1 | DEBUG | com.server.ClientsDAO | Queried for Clients

[Jun 10 10:16:35] pool-16-thread-1 | DEBUG | com.server.Heartbeat | Fetching Clients from cache, duration = 5. timeunit = MINUTES
[Jun 10 10:16:35] pool-16-thread-1 | DEBUG | com.server.ClientsDAO | Getting DB connection
[Jun 10 10:16:35] pool-16-thread-1 | DEBUG | com.server.ClientsDAO | Queried for Clients

[Jun 10 10:17:05] pool-16-thread-1 | DEBUG | com.server.Heartbeat | Fetching Clients from cache, duration = 5. timeunit = MINUTES
[Jun 10 10:17:05] pool-16-thread-1 | DEBUG | com.server.ClientsDAO | Getting DB connection
[Jun 10 10:17:05] pool-16-thread-1 | DEBUG | com.server.ClientsDAO | Queried for Clients

您永远不会重复使用 Suppliers.memoizeWithExpiration 所以它总是一个新调用

您在每次调用时都会创建一个新的记忆供应商,因此基本上每次都会进行一次新调用,因为新的记忆供应商是空的,因此会传播调用以填充自身。您应该只创建一次记忆供应商,然后像这样重复调用它:

private final Supplier<List<Client>> getClientsSupplier = Suppliers.memoizeWithExpiration(ClientsDao::getClients, Server.CACHE_REFRESH_DURATION, Server.CACHE_REFRESH_TIMEUNIT);

public List<Client> getClients() {
  return getClientsSupplier.get();
}