GoFramework框架简介(五)缓存篇

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 map, int timeToLive, TimeUnit timeUnit, String namespace);

    public Map mget(Collection keys, String namespace);

    public void mdelete(Collection 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 extends AbstractDubboIntegrationService implements IDubboCache{

    /**
     * 设置缓存过期的分钟数
     * @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 result = (CacheContainer) cacheService.get(String.valueOf(key), adjustNameSpace);
            if(result == null){
                info("缓存不存在或已失效,需要重新查询信息。");
                result = new CacheContainer(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 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缓存,因此建议优先使用。但本地缓存因存放在各自虚拟机中,所以在多节点部署时需要考虑数据同步更新问题。

转载于:https://www.cnblogs.com/wuyuhuanzhen/p/9285038.html

你可能感兴趣的:(GoFramework框架简介(五)缓存篇)