缓存接口流程
1、需要传递过来rediscache
2、根据key拿到对应的string类型的value值,判断value是否为null 走第3步,不为null走第4步
3、根据从db拿值的方法函数取出对应的value,并对此次的value再次判空处理,为null第5步,不为null第6步
4、判断是否与设置的缓存穿透的值相等,如果相等直接返回null,不相等则进行反序列化,处理成对应的返回值类型返回数据
5、直接将缓存穿透的值设置到该key对应的value里,并返回null
6、将值设置到该key对应的value里,并返回该对象
在下面的缓存接口里,基于java8的函数式编程做了一次不侵占如何获取数据的基于泛型的方法的抽象,也统一做了一次可以在配置中心配置缓存开关并记录打点的方法
public <V, F extends RedisCache> V getCache(F f, String key, String metricKey, GetValueMethodInterface<V> getValueMethod, boolean preventPenetrateFlag, int expireSeconds, TypeToken<V> typeToken) throws ServiceException {
//全局缓存开关配置
if (HuskarSwitchCommonSettings.closeCache()) {
TraceUtils.notHitCache();
return getValueMethod.getValue();
}
//指定缓存key的配置
if (!StringUtils.isEmpty(metricKey)) {
//指定类型关闭缓存
if (HuskarSwitchCommonSettings.closeDataCache(metricKey)) {
TraceUtils.notHitCache(MetricEnum.MISS_CACHE.getType(), metricKey);
return getValueMethod.getValue();
}
}
//缓存的计算
String value = f.get(key);
if (value == null) {
if (!StringUtils.isEmpty(metricKey)) {
TraceUtils.notHitCache(MetricEnum.MISS_CACHE.getType(), metricKey);
}
V v = getValueMethod.getValue();
if (v == null) {
if (preventPenetrateFlag) {
f.set(key, PREVENT_PENETRATE_TIME_SECONDS, PREVENT_PENETRATE_VALUE);
} else {
f.set(key, expireSeconds, null);
}
return null;
}
f.set(key, expireSeconds, VJson.writeAsString(v));
return v;
}
//命中缓存
if (!StringUtils.isEmpty(metricKey)) {
TraceUtils.hitCache(MetricEnum.HIT_CACHE.getType(), metricKey);
}
if (PREVENT_PENETRATE_VALUE.equals(value)) {
TraceUtils.incr(MetricEnum.PREVENT_PENETRATE);
return null;
}
return VJson.read(value, typeToken);
}
Redis常用数据类型String、List、Hash、Set、ZSet;