1. 本地缓存采用的是Guava Cache的expireAfterWrite刷新机制。
Guava Cache本地缓存基于expireAfterWrite刷新缓存机制。
1)expireAfterWrite缓存刷新是在指定的时间段内没有更新就会被回收。所以对缓存数据时效性高,可以考虑使用expireAfterWrite,使每次更新缓存后在指定时间让缓存失效,
然后重新加载缓存。而Guaua Cache会限制只有1个加载操作并且进行加锁,其他请求必须阻塞等待这个加载操作完成后,才能获得锁和获取缓存值,这样是有一些性能损耗。
2)在CacheLoader<K, V> 的V load(K var1)方法对返回值如果是Null是会抛异常(com.google.common.cache.CacheLoader$InvalidCacheLoadException: CacheLoader returned null for key hi.),
会造缓存刷新失败,所以必需要保证每次加载缓存的数据是非空的值。
² 考虑expireAfterWrite以上原因。首先小飞机服务项目缓存的数据都是基础数据,更新的时效性相对不高,所以更改另外一种刷新机制refreshAfterWrite(缓存项上一次更新操作之后多久时间会被定时刷新),
refreshAfterWrite刷新的过程是异步处理的(定时刷新时调用下面reload异步方法)。在刷新操作进行时,缓存值的获取仍然可以向其他线程返回旧值,并不会阻塞等待新值加载完成才能得到缓存值。
另外刷新过程抛出异常,缓存将保留旧值,异常信息可以记录在Clog日志。
CacheBuilder.newBuilder() .refreshAfterWrite(duration, unit) .build(new CacheLoader<String, T>() { @Override public T load(String key) throws Exception { // TODO
} @Override public ListenableFuture<T> reload(final String key, T oldValue) { // TODO
} });