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依赖

<!--jetcache缓存 -->
<dependency>
    <groupId>com.alicp.jetcache</groupId>
    <artifactId>jetcache-starter-redis</artifactId>
    <version>${jetcache.latest.version}</version>
</dependency>

配置文件

参考文档: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<Integer, User> 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<Integer, User> 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失效也会报上述错误。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,743评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,296评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,285评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,485评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,581评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,821评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,960评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,719评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,186评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,516评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,650评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,329评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,936评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,757评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,991评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,370评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,527评论 2 349

推荐阅读更多精彩内容