205. jetcache:你需要知道的小技巧

【视频&交流平台】

à Spring Boot视频:http://t.cn/R3QepWG

à Spring Cloud视频:http://t.cn/R3QeRZc

à Spring Boot Shiro视频:http://t.cn/R3QDMbh

à Spring Boot交流平台:http://t.cn/R3QDhU0

à Spring Boot 2.0 SpringData和JPA视频:

http://t.cn/R1pSojf

说明

(1)Spring Boot 版本:2.0.3.RELEASE

(2)jetcache版本:2.5.2

(3)JDK:1.8

前言

       在前一篇文章中介绍了在Spring Boot中怎么使用JetCache,但是对于实际的使用这是不够的,本篇文章就讲讲一些小技巧。

       在写之前,祝大家父亲节快乐,记得给爸爸打个电话,问声好。有你在,才是梦开始的地方。

一、缓存name的指定

 

对于@CreateCache指定的缓存对象,默认生成的缓存的key的名称是:

c.k.j.d.c.TestCacheInstanceController.cache100

       对于@Cached指定的方法缓存,默认生成的缓存的key的名称是:

c.k.j.d.s.ArticleTypeService.getById(J)[102]

       那么如何指定呢?

@Cached(name="ArticleType.getById")
public ArticleType getById(long id){}

 

缓存的名称name,不是必须的,如果没有指定,会使用类名+方法名。name会被用于远程缓存的key前缀。另外在统计中,一个简短有意义的名字会提高可读性。

二、缓存失效时间

       这个Spring Cache这个就不能指定,未来官方是否会支持呢,给官方提个issue吧。

JetCache就是可以设置的:

@Cached(name="ArticleType.getById",expire=3600)
public ArticleType getById(long id) {}

 

       该Cache实例的默认超时时间定义,注解上没有定义的时候会使用全局配置,如果此时全局配置也没有定义,则取无穷大。缓存失效时间单位是秒,3600秒=1小时。

       当然失效时间的单位,你可以通过属性timeUnit(TimeUnit.SECONDS )重新定义的。

 

三、二级缓存

       这里的缓存是内存+远程缓存:

@Cached(name="ArticleType.getById",expire=3600,cacheType=CacheType.BOTH)
public ArticleType getById(long id) {}

这里通过cacheType属性,可以设置缓存方式,可选值:

LOCAL:内存缓存,只会存在内存中,并不会存储到redis中。

REMOTE:远程缓存。

BOTH:内存缓存+远程缓存。

 

四、内存中的元素个数限制

       对于内存中的缓存,是需要控制缓存的个数的,缓存个数过多的话,很有可能就会内存溢出了,那么对于JetCache是可以设置内存缓存的个数的:

@Cached(name="ArticleType.getById",expire=3600,cacheType=CacheType.LOCAL,localLimit=2)
public ArticleType getById(long id) {}

如果cacheType为CacheType.LOCAL或CacheType.BOTH,这个参数指定本地缓存的最大元素数量,以控制内存占用。注解上没有定义的时候会使用全局配置,如果此时全局配置也没有定义,则取100。

五、非堵塞的获取一个锁

AutoReleaseLock tryLock(K key, long expire, TimeUnit timeUnit)
boolean tryLockAndRun(K key, long expire, TimeUnit timeUnit, Runnable action)

非堵塞的尝试获取一个锁,如果对应的key还没有锁,返回一个AutoReleaseLock,否则立即返回空。如果Cache实例是本地的,它是一个本地锁,在本JVM中有效;如果是redis等远程缓存,它是一个不十分严格的分布式锁。锁的超时时间由expire和timeUnit指定。多级缓存的情况会使用最后一级做tryLock操作。用法如下:

  // 使用try-with-resource方式,可以自动释放锁
  try(AutoReleaseLock lock = cache.tryLock("MyKey",100, TimeUnit.SECONDS)){
     if(lock != null){
        // do something
     }
  }

上面的代码有个潜在的坑是忘记判断if(lock!=null),所以一般可以直接用tryLockAndRun更加简单:

  boolean hasRun = tryLockAndRun("MyKey",100, TimeUnit.SECONDS), () -> {
    // do something
  };

tryLock内部会在访问远程缓存失败时重试,会自动释放,而且不会释放不属于自己的锁,比你自己做这些要简单。当然,基于远程缓存实现的任何分布式锁都不会是严格的分布式锁,不能和基于ZooKeeper或Consul做的锁相比。

六、大写API

V get(Kkey)这样的方法虽然用起来方便,但有功能上的缺陷,当get返回null的时候,无法断定是对应的key不存在,还是访问缓存发生了异常,所以JetCache针对部分操作提供了另外一套API,提供了完整的返回值,包括:

CacheGetResult<V> GET(K key);
MultiGetResult<K, V> GET_ALL(Set<? extends K> keys);
CacheResult PUT(K key, V value);
CacheResult PUT(K key, V value, long expireAfterWrite, TimeUnit timeUnit);
CacheResult PUT_ALL(Map<? extends K, ? extends V> map);
CacheResult PUT_ALL(Map<? extends K, ? extends V> map, long expireAfterWrite, TimeUnit timeUnit);
CacheResult REMOVE(K key);
CacheResult REMOVE_ALL(Set<? extends K> keys);
CacheResult PUT_IF_ABSENT(K key, V value, long expireAfterWrite, TimeUnit timeUnit);

这些方法的特征是方法名为大写,与小写的普通方法对应,提供了完整的返回值,用起来也稍微繁琐一些。例如:

CacheGetResult<ArticleType> result = cache.GET(articleType.getId());
if(result.isSuccess()) {
    ArticleType articleType2 = result.getValue();
    System.out.println(articleType2);
}else if(result.getResultCode() == CacheResultCode.NOT_EXISTS) {
     System.out.println("cache miss:" + articleType.getId());
}else if(result.getResultCode() == CacheResultCode.EXPIRED) {
     System.out.println("cache expired:" + articleType.getId());
}else {
    System.out.println("cache get error:" + articleType.getId());
}

       好了本篇文章就介绍到这里。

《九月九日忆山东兄弟》

作者:王维

独在异乡为异客,每逢佳节倍思亲。

遥知兄弟登高处,遍插茱萸少一人。

       端午佳节,大家记得给家人问声好,在外记得吃粽子。

历史相关文章:

203. 阿里jetcache

204. jetcache:在Spring Boot中怎么玩?

 

微信公众号「SpringBoot」最近更新:

214. Spring Security:概述
213.Spring Boot 2.0新特性:配置绑定
212. Spring Boot WebFlux:响应式Spring Data之MongoDB
211. Spring Boot WebFlux:使用篇
210. Spring Boot WebFlux:概念篇
Java8新特性:Stream:实战篇
为了更勇敢,你可以害怕@一禅小和尚
Java8新特性:Stream:基础篇
Java8新特性:方法引用
209. SpringBoot quartz:sqlserver启动只有 DECLARE CURSOR 才允许使用...
风口之上,我是那头猪嘛?
Java8新特性:Lambda表达式: 摸摸里面
Java8新特性:Lambda表达式:过关斩将:使用场景
Java8新特性:Lambda表达式:小试牛刀
下雨天,适合学「Spring Boot」
Java8新特性:接口的默认方法
208. Spring Boot Swagger2:排序 – 漂游记
207. Spring Boot Swagger2:极简方式
我读的书很多,但都没有你好看【一禅录】
206. Spring Boot 2.0 Swagger2:使用
205. Spring Boot 2.0 Swagger2:初识Swagger
当要离开的时候,我却动情了
205. jetcache:你需要知道的小技巧
204. jetcache:在Spring Boot中怎么玩?

 搜索「springboot」或者扫描以下二维码即可关注:

悟纤 CSDN认证博客专家 知远公司创始人 架构师 访问1000万+
「公众号SpringBoot」:
①阿里巴巴前高级研发工程师;
②估值20亿美金的Blued架构师;
③北京知远公司创始人;
④浙江甄才公司架构师;
⑤云课堂学员10000+;
⑥博客访问量1000万+;
⑦10年互联网行业从业;
⑧360万的访问《从零开始学SprngBoot》作者;
⑨技术加盟多个独立项目。
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页
实付 9.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值