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<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缓存,因此建议优先使用。但本地缓存因存放在各自虚拟机中,所以在多节点部署时需要考虑数据同步更新问题。

posted @ 2018-07-09 17:52  无语还真  阅读(735)  评论(0编辑  收藏  举报