Guava缓存项目实战
程序员文章站
2022-07-13 17:37:18
...
项目中涉及到数据缓存,对一致性要求还行,本来打算用Guava做。后来发现6台机器且数据量3亿左右,内存大小和路由达不到要求。换成redis做缓存,但是guava代码已经初步写好,放在此处用于记录。
/**
* 〈一句话功能简述〉<br>
* 〈功能详细描述〉Guava缓存处理抽象类
*
* @author wangzha
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public abstract class AbstractGuavaCache<K, V> {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractGuavaCache.class);
/**
* loadingCache 核心实例
*/
private volatile LoadingCache<K, V> loadingCache;
/**
* 并发级别
*/
private int concurrencyLevel;
/**
* 缓存超时时间
*/
private long expireTime;
/**
* 初始容量
*/
private int initialCapacity;
/**
* 最大容量
*/
private long maxSize;
protected AbstractGuavaCache(int concurrencyLevel, long expireTime, int initialCapacity, long maxSize) {
this.concurrencyLevel = concurrencyLevel;
this.expireTime = expireTime;
this.initialCapacity = initialCapacity;
this.maxSize = maxSize;
}
/**
* 〈一句话功能简述〉<br>
* 〈功能详细描述〉
*
* @Param
* @return
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
**/
public LoadingCache<K, V> getCache() {
// 双重检查锁-防止重复加载
if (loadingCache == null) {
synchronized (this) {
if (loadingCache == null) {
loadingCache = CacheBuilder.newBuilder()
// 设置并发级别为8
.concurrencyLevel(concurrencyLevel)
// 设置多久不读缓存废弃
.expireAfterAccess(expireTime, TimeUnit.HOURS)
// 设置初始条数
.initialCapacity(initialCapacity)
// 设置最大条数,超过则按照LRU策略淘汰缓存
.maximumSize(maxSize)
// 设置要统计缓存的命中率
.recordStats()
// 设置缓存的移除通知
.removalListener(removalNotification -> {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("{} was moved,cause is {}", removalNotification.getKey(),
removalNotification.getCause());
}
}).build(
// 设置缓存不存在时,自动加载入缓存
new CacheLoader<K, V>() {
@Override
public V load(K k) throws Exception {
return fetchData(k);
}
});
}
}
}
if (LOGGER.isInfoEnabled()) {
LOGGER.info("本地缓存{}初始化成功", this.getClass().getSimpleName());
}
return loadingCache;
}
/**
* 〈一句话功能简述〉<br>
* 〈功能详细描述〉载入数据
*
* @Param
* @return
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
**/
protected abstract V fetchData(K k);
public int getConcurrencyLevel() {
return concurrencyLevel;
}
public void setConcurrencyLevel(int concurrencyLevel) {
this.concurrencyLevel = concurrencyLevel;
}
public long getExpireTime() {
return expireTime;
}
public void setExpireTime(long expireTime) {
this.expireTime = expireTime;
}
public int getInitialCapacity() {
return initialCapacity;
}
public void setInitialCapacity(int initialCapacity) {
this.initialCapacity = initialCapacity;
}
public long getMaxSize() {
return maxSize;
}
public void setMaxSize(long maxSize) {
this.maxSize = maxSize;
}
}
/**
* 〈一句话功能简述〉<br>
* 〈功能详细描述〉默认Guava缓存管理类
*
* @author wangzha
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class DefaultGuavaCacheManage {
public static final Logger LOGGER = LoggerFactory.getLogger(DefaultGuavaCacheManage.class);
/**
* 缓存包装
*/
private static AbstractGuavaCache<String, Object> wrapper;
/**
* 〈一句话功能简述〉<br>
* 〈功能详细描述〉初始化缓存容器
*
* @Param
* @return
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
**/
@SuppressWarnings("unchecked")
public static boolean initGuaveCache() {
wrapper = DefaultGuavaCache.getInstance();
if (wrapper != null) {
return true;
} else {
LOGGER.error("Fail to init Guava Cache !");
return false;
}
}
/**
* 〈一句话功能简述〉<br>
* 〈功能详细描述〉通过key获取缓存值
*
* @Param key 缓存key
* @return
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
**/
public static Object get(String key) {
Object object = null;
try {
object = wrapper.getCache().get(key);
} catch (ExecutionException e) {
LOGGER.error("get Guava cache exception");
}
return object;
}
/**
* 〈一句话功能简述〉<br>
* 〈功能详细描述〉通过key获取缓存值,如果没有采取一定措施
*
* @Param key 缓存的key
* @return callable 回调函数
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
**/
public static Object getOrDo(String key, Callable callable) {
Object object = null;
try {
wrapper.getCache().get(key, callable);
} catch (ExecutionException e) {
LOGGER.error("getOrDo Guava cache exception");
}
return object;
}
/**
* 〈一句话功能简述〉<br>
* 〈功能详细描述〉清除指定key缓存
*
* @Param key 缓存的key
* @return
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
**/
public static void invalidate(String key) {
wrapper.getCache().invalidate(key);
}
/**
* 〈一句话功能简述〉<br>
* 〈功能详细描述〉清除所有缓存
*
* @Param
* @return
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
**/
public static void inalidateAll(){
wrapper.getCache().invalidateAll();
}
/**
* 静态内部类实现单例
*
* @param <String>
* @param <Object>
*/
static class DefaultGuavaCache<String, Object> extends AbstractGuavaCache<String, Object> {
private static AbstractGuavaCache guavaCache = new DefaultGuavaCache(
CacheScmCfg.getInteger(CacheScmCfg.DEFAULT_GUAVA_CONCURRENCY_LEVEL_KEY),
CacheScmCfg.getInteger(CacheScmCfg.DEFAULT_GUAVA_EXPIRE_TIME_KEY),
CacheScmCfg.getInteger(CacheScmCfg.DEFAULT_GUAVA_INITIALCAPACITY_KEY),
CacheScmCfg.getInteger(CacheScmCfg.DEFAULT_GUAVA_MAXSIZE_KEY));
public static AbstractGuavaCache getInstance() {
return guavaCache;
}
private DefaultGuavaCache(int concurrencyLevel, long expireTime, int initialCapacity, long maxSize) {
super(concurrencyLevel, expireTime, initialCapacity, maxSize);
}
@Override
protected Object fetchData(String s) {
//具体操作
return null;
}
}
}