GoFramework框架简介(五)缓存篇

127 阅读2分钟

Redis缓存

框架对Redis进行了基础的调用封装,接口类为:org.go.framework.cache.CacheService,提供了众多方法可供使用。Dubbo服务端及Web端都可以直接引用该服务实例。

public void put(String key, Object value, int timeToLive, TimeUnit timeUnit, String namespace); public void put(String key, Object value, int timeToIdle, int timeToLive, TimeUnit timeUnit, String namespace); public boolean exists(String key, String namespace); public Object get(String key, String namespace); public Object get(String key, String namespace, int timeToIdle, TimeUnit timeUnit); public void delete(String key, String namespace); public void mput(Map<String, Object> map, int timeToLive, TimeUnit timeUnit, String namespace); public Map<String, Object> mget(Collection<String> keys, String namespace); public void mdelete(Collection<String> keys, String namespace); public boolean containsKey(String key, String namespace); public boolean putIfAbsent(String key, Object value, int timeToLive, TimeUnit timeUnit, String namespace); public long increment(String key, long delta, int timeToLive, TimeUnit timeUnit, String namespace); public boolean supportsTimeToIdle(); public boolean supportsUpdateTimeToLive(); public void invalidate(String namespace);

另外,还提供了一个缓存模板抽象类org.go.framework.cache.CacheService,可以快速实现缓存功能。

public abstract class AbstractBaseRedisCache<K, V> extends AbstractDubboIntegrationService implements IDubboCache<K, V>{ /** * 设置缓存过期的分钟数 * @return */ protected abstract Integer getExpiredMinutes(); /** * 缓存业务逻辑实现方法 * @param cacheKey * @return * @throws PendingException */ protected abstract V query(K cacheKey) throws PendingException; /** * 设置缓存查询失败的返回码 * @return */ protected abstract ResCode getErrResCode(); /** * 指定缓存的命名空间 * @return */ protected abstract String getNameSpace(); /** * 缓存的版本号,默认值为0 * 如果缓存的数据结构有变动,则需要修改版本号 * @return */ protected abstract int getVersion(); @Autowired private CacheService cacheService; /** * 根据Key查询缓存对象 * @param key 缓存的Key * @return * @throws PendingException 需要进行处理 */ @SuppressWarnings("unchecked") public V get(K key) throws PendingException{ try { //根据版本号调整后的命名空间 String adjustNameSpace = getNameSpace() + getVersion(); //从redis中查询缓存内容 CacheContainer<V> result = (CacheContainer<V>) cacheService.get(String.valueOf(key), adjustNameSpace); if(result == null){ info("缓存不存在或已失效,需要重新查询信息。"); result = new CacheContainer<V>(query(key)); cacheService.put(String.valueOf(key), result, getExpiredMinutes(), TimeUnit.MINUTES, adjustNameSpace); } return result.getObject(); } catch (Exception ex) { error("缓存查询失败!", ex); throw new PendingException(getErrResCode().getCode(), getErrResCode().getInfo()); } } /** * 清除缓存 * @param key * @throws PendingException */ public void clearCache(K key) throws PendingException{ try { //根据版本号调整后的命名空间 String adjustNameSpace = getNameSpace() + getVersion(); //在redis中清除缓存信息 cacheService.delete(String.valueOf(key), adjustNameSpace); }catch (Exception ex) { error("缓存查询失败!", ex); ResCode.REDIS_CACHE_DEL_ERR.throwException(); } } ... }

实现示例:

@Component public class UserInfoRedisCache extends AbstractBaseRedisCache<Integer, UserInfoItem> implements IUserInfoRedisCache { @Reference(version = "1.0.0") private UserInfoFacade userInfoFacade; @Override protected int getVersion() { return 0; //版本号 } @Override protected String getNameSpace() { return CacheNameSpaceConstants.User.USER_INFO_CACHE; } @Override protected Integer getExpiredMinutes() { return 60 * 24;// 一天 } @Override protected ResCode getErrResCode() { return ResCode.userInfoCacheQueryFailed; } @Override protected UserInfoItem query(Integer userId) throws PendingException { // 查询用户信息 UserInfoRspDto userInfoResDto = getUserInfoById(userId); // 转换返回结果 return BeanMapping.map(userInfoResDto, UserInfoItem.class); } /** * 根据用户Id查询用户信息 * * @param userId * @return * @throws PendingException */ private UserInfoRspDto getUserInfoById(Integer userId) throws PendingException { // 组装查询条件 GetUserInfoReqDto getUserInfoReqDto = new GetUserInfoReqDto(); getUserInfoReqDto.setUserId(userId); // 调用dubbo服务进行查询 UserInfoRspDto userInfoResDto = userInfoFacade.getUserInfo(getUserInfoReqDto); // 如失败则抛出异常,用户查询没有空的概念 userInfoResDto.throwExceptionIfFailed(); return userInfoResDto; } }

本地缓存

本地缓存的模板抽象类是org.go.framework.cache.CacheService,实现机制原理与redis差不多,采用Guava的底层缓存框架实现。

本地缓存性能远高于Redis缓存,因此建议优先使用。但本地缓存因存放在各自虚拟机中,所以在多节点部署时需要考虑数据同步更新问题。