JetCache接入文档

jetcache接入文档

官方文档

https://github.com/alibaba/jetcache/wiki
参考文档:https://blog.csdn.net/nb7474/article/details/84555665?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.pc_relevant_default&utm_relevant_index=1

jetcache简介

阿里开源的缓存框架,它提供了比spring cache框架更加强大的注解。其注解支持原生的TTL,二阶段缓存(本地和远程),分布式的自动缓存刷新机制以及分布式锁,还可以自动采集对缓存的访问统计(包括TPS,缓存命中率等)。本地缓存可以使用LinkedHashMapCacheCaffeineCache,远程缓存可以使用RedisCache

spring boot项目接入

添加maven依赖



    com.alicp.jetcache
    jetcache-starter-redis
    ${jetcache.latest.version}

配置文件

参考文档:https://github.com/alibaba/jetcache/wiki/Config
配置示例:

jetcache:
  # 每隔多长时间输出一次缓存访问统计信息,0表示不输出
  statIntervalMinutes: 1
  # 如果设置为`true`,生成的缓存名称中会带有`area`前缀(比如下面的`default_`,`longTime_`,`shortTime_`等等),建议设置为`false`
  areaInCacheName: false 
  # 当缓存名称设置成自动生成时,匹配该前缀的会被切掉。建议手动设置缓存名称,方便查看缓存统计信息
  hidePackages: com.springboot.cloud 
  # 本地缓存设置,type支持`caffeine`和`LinkedHashMapCache`
  local: # 这里指定了3个`area`:default,longTime,shortTime可以按需配置
    # 默认2小时本地缓存
    default:
      type: caffeine
      keyConvertor: fastjson
      expireAfterWriteInMillis: 3600000 # 写的过期时间
      expireAfterAccessInMillis: 1800000 # 读的过期时间,本地缓存才支持
    # 長時本地緩存,主要用于要求时效一般
    longTime:
      type: caffeine
      keyConvertor: fastjson
      expireAfterWriteInMillis: 300000
      expireAfterAccessInMillis: 180000
    # 短時本地緩存,主要用于要求时效较高的配置
    shortTime:
      type: caffeine
      keyConvertor: fastjson
      expireAfterWriteInMillis: 60000
      expireAfterAccessInMillis: 40000
  remote: # 这里指定了3个`area`:default,longTime,shortTime可以按需配置
    # 默认2小时的远程缓存
    default:
      type: redis
      expireAfterWriteInMillis: 43200000
      keyConvertor: fastjson
      valueEncoder: kryo # 只有remote缓存需要,支持`java`和`kryo`
      valueDecoder: kryo # 只有remote缓存需要,支持`java`和`kryo`
      poolConfig:
        minIdle: 5
        maxIdle: 20
        maxTotal: 50
      host: ${REDIS_HOST}
      port: ${REDIS_PORT}
      password: ${REDIS_PASSWORD}
    # 长时远程緩存,主要用于要求时效要求一般的集中式缓存
    longTime:
      type: redis
      expireAfterWriteInMillis: 7200000
      keyConvertor: fastjson
      valueEncoder: kryo
      valueDecoder: kryo
      poolConfig:
        minIdle: 5
        maxIdle: 20
        maxTotal: 50
      host: ${REDIS_HOST}
      port: ${REDIS_PORT}
      password: ${REDIS_PASSWORD}
    # 短時远程緩存,主要用于要求时效较高的集中式缓存
    shortTime:
      type: redis
      expireAfterWriteInMillis: 300000
      keyConvertor: fastjson
      valueEncoder: kryo
      valueDecoder: kryo
      poolConfig:
        minIdle: 5
        maxIdle: 20
        maxTotal: 50
      host: ${REDIS_HOST}
      port: ${REDIS_PORT}
      password: ${REDIS_PASSWORD}

使用示例

  1. @Cached添加缓存(通常和@CacheUpdate,@CacheInvalidate配套使用)
    核心参数释义:
area: 配置文件中关联的缓存域,比如上面的`default`,`longTime`,`shortTime`。默认`default`,继承缓存域的中的相关配置  
cacheType: 枚举值。`BOTH`:本地和远程都缓存,`LOCAL`:本地缓存,`REMOTE`远程缓存  
localLimit: 本地缓存条目限制,仅对本地缓存有效
key: 缓存的key,支持SpEL表达式
condition: 前置条件(方法执行前判断),结果为false则不添加缓存,支持SpEL表达式
postCondition: 后置条件(方法执行后判断),结果为false则不添加缓存,支持SpEL表达式(可以通过#result获取返回结果)。

代码示例:

@Cached(area = "longTime", cacheType = CacheType.BOTH, localLimit = 100,
        name = "userCache::", key = "#userId", expire = 3600, condition = "", postCondition = "")
@Override
public User getUserById(int userId) {
    // 访问db
    return getFromDb();
}
  1. @CacheUpdate更新缓存
    核心参数释义:
key: 缓存的key,支持SpEL表达式(建议设置一个bean,该bean专门用于条件判断,格式为:`bean('testService').方法名`),`testService`为bean的名称
condition: 后置条件(方法执行后判断),结果为false则不更新缓存,支持SpEL表达式(可以通过#result获取返回结果)。
multi: 如果`key`和`value`都是数组或者迭代器,设置为true时则以键值对的方式更新缓存

代码示例:

@CacheUpdate(name = "userCache::", key = "bean('testService').getKey()", value = "#user", condition = "bean('testService').predicate(#user,#result)")
@Override
public int updateUser(User user) {
    // 访问db
    return updateFromDb();
}

@Service
public class TestService implements ITestService {
    @Override
    public boolean predicate(User user, int size) {
        return true;
    }

    @Override
    public String getKey() {
        return "2";
    }
}
  1. @CacheInvalidate缓存失效
    核心参数释义:
multi: 如果`key`和`value`都是数组或者迭代器,设置为true时则以键值对的方式使缓存失效  

代码示例:

@CacheInvalidate(name = "userCache::", key = "#userId", multi = true)
@Override
public void deleteUser(int userId) {
    // 访问db
    return deleteFromDb();
}
  1. @CreateCache@CacheRefresh创建缓存并设置缓存自动刷新策略
    @CreateCache注解用来生成缓存
    @CacheRefresh注解对生成的缓存执行刷新策略。在remote环境中,该刷新操作是全局锁定的(使用分布式锁),避免多个服务并发的刷新指定key的缓存
    核心参数释义:
refresh: 定时刷新缓存(下面的`init`有示例)。在第一次调用`get`方法时候触发定时器,只是`put`不会触发定时器
stopRefreshAfterLastAccess: 最后一次调用`get`方法之后,多久停止对缓存的刷新

代码示例:

@CreateCache(name = "userCache::", expire = 1000, cacheType = CacheType.REMOTE)
@CacheRefresh(refresh = 10, stopRefreshAfterLastAccess = 20)
@CachePenetrationProtect
private Cache userCache;

@PostConstruct
public void init() {
    this.userCache.config().setLoader(this::loadFromDb);
}

private User loadFromDb(Integer key) {
    log.info("Refresh value from key:{}", key);
    User user = new User();
    user.setId(key);
    user.setName("clp");
    return user;
}

@Override
public User getUserById(int userId) {
    return userCache.get(userId);
}

@Override
public int updateUser(User user) {
    this.userCache.put(user.getId(), user);
    return user.getId();
}
  1. 分布式锁
    使用tryLockAndRun方式实现分布式锁的相关功能
    代码示例:
@CreateCache(name = "userCache::", expire = 1000, cacheType = CacheType.REMOTE)
@CacheRefresh(refresh = 10, stopRefreshAfterLastAccess = 20)
@CachePenetrationProtect
private Cache userCache;

@PostConstruct
public void init() {
    this.userCache.config().setLoader(this::loadFromDb);
    this.userCache.tryLockAndRun(1, 60, TimeUnit.SECONDS, () -> heavyDatabaseOperation());
}

@SneakyThrows
private void heavyDatabaseOperation(){
    Thread.sleep(3000);
}

jetcache统计功能

通过statIntervalMinutes参数设置统计打印周期,可以统计缓存的以下指标
qps:每秒请求次数
rate: 缓存命中率
get: 方法执行的次数
hit: 缓存命中次数
fail: 缓存失效的次数
expire: 过期数量
avgLoadTime: 平均加载时间
maxLoadTime: 最大加载时间

统计示例.png

jetcache缺点

上面说过@Cached注解通常和@CacheUpdate,@CacheInvalidate配套使用。其内部的实现原理是通过注解@EnableMethodCache指定的basePackages
扫描所有标注了上述3个注解的方法,然后本地缓存。后续通过@CacheInvalidate标注缓存失效,其首先会通过key找对应的@Cached,如果找不到则会抛出
异常:can't find @Cached definition with area=default...这里会产生一个问题:假设A服务通过@Cached新增缓存,然后B服务通过@CacheUpdate
@CacheInvalidate更新或删除缓存则会出现上述问题。还有通过一般方式添加的缓存(不通过jetcache框架),想用@CacheInvalidate失效也会报上述错误。

你可能感兴趣的:(JetCache接入文档)