目录
[2.1 缓存分类](#2.1 缓存分类)
[2.1.1 本地缓存](#2.1.1 本地缓存)
[2.1.2 分布式缓存](#2.1.2 分布式缓存)
[2.2 独立缓存的问题](#2.2 独立缓存的问题)
[2.2.1 缓存雪崩问题](#2.2.1 缓存雪崩问题)
[2.2.2 对宽带压力大](#2.2.2 对宽带压力大)
[2.2.3 运行效率低](#2.2.3 运行效率低)
[2.3 多级缓存方案](#2.3 多级缓存方案)
[2.3.1 多级缓存实践方案推荐](#2.3.1 多级缓存实践方案推荐)
[3.1 jetcache概述](#3.1 jetcache概述)
[3.2 jetcache 特性](#3.2 jetcache 特性)
[3.3 jetcache 应用场景](#3.3 jetcache 应用场景)
[3.3.1 热点数据缓存](#3.3.1 热点数据缓存)
[3.3.2 多级缓存融合](#3.3.2 多级缓存融合)
[3.3.3 支撑高并发读写](#3.3.3 支撑高并发读写)
[3.3.4 高速访问查询](#3.3.4 高速访问查询)
[3.4 JetCache API使用](#3.4 JetCache API使用)
[3.4.1 缓存管理](#3.4.1 缓存管理)
[3.4.2 注解支持](#3.4.2 注解支持)
[3.4.3 缓存类型](#3.4.3 缓存类型)
[3.4.4 Spring 集成支持](#3.4.4 Spring 集成支持)
[4.1 缓存支持类型](#4.1 缓存支持类型)
[4.1.1 本地缓存类型](#4.1.1 本地缓存类型)
[4.1.2 远程缓存支持类型](#4.1.2 远程缓存支持类型)
[4.2 maven 依赖](#4.2 maven 依赖)
[4.3 本地缓存方案](#4.3 本地缓存方案)
[4.3.1 application 配置文件](#4.3.1 application 配置文件)
[4.3.2 新增测试方法](#4.3.2 新增测试方法)
[4.3.3 新增测试接口](#4.3.3 新增测试接口)
[4.3.4 启动类](#4.3.4 启动类)
[4.3.5 效果测试](#4.3.5 效果测试)
[4.4 远程缓存方案](#4.4 远程缓存方案)
[4.4.1 application 添加如下配置](#4.4.1 application 添加如下配置)
[4.4.2 修改业务层方法注解参数](#4.4.2 修改业务层方法注解参数)
[4.4.3 启动服务测试效果](#4.4.3 启动服务测试效果)
[4.4.4 字段级缓存@CreateCache](#4.4.4 字段级缓存@CreateCache)
[4.5 同时开启本地缓存和远程缓存](#4.5 同时开启本地缓存和远程缓存)
[4.5.1 修改配置属性值](#4.5.1 修改配置属性值)
[4.5.2 业务层其他方法](#4.5.2 业务层其他方法)
[4.6 jetcache 核心注解](#4.6 jetcache 核心注解)
[4.6.1 @Cached注解](#4.6.1 @Cached注解)
[4.6.2 @CacheUpdate注解](#4.6.2 @CacheUpdate注解)
[4.6.3 @CacheInvalidate注解](#4.6.3 @CacheInvalidate注解)
[4.6.4 @CacheRefresh注解](#4.6.4 @CacheRefresh注解)
[4.6.5 @CachePenetrationProtect注解](#4.6.5 @CachePenetrationProtect注解)
[4.7 jetcache使用总结](#4.7 jetcache使用总结)
一、前言
缓存对于一个高并发场景下的微服务应用来说具有重要的作用,不管是在架构选型还是设计阶段,缓存都是应用扛高并发提升吞吐量的有效手段。缓存对于大多数开发的同学来说并不陌生,一个基本的缓存使用流程如下:
简而言之,缓存的使用流程可归纳如下:
- 请求到达服务端;
- 先从缓存获取数据,缓存命中直接返回;
- 缓存未命中,查询数据库,然后返回数据,同时同步缓存;
二、多级缓存问题
2.1 缓存分类
2.1.1 本地缓存
本地缓存指的是应用内部的缓存,也叫进程缓存。最大的优点是应用和cache是在同一个进程内部,请求缓存快,没有过多的网络开销。本地缓存的有的很多,具体来说:
- 在单应用不需要集群支持或者集群情况下各节点无需互相通知的场景下使用本地缓存较合适;
- 缺点是缓存跟应用程序耦合,多个应用程序无法直接的共享缓存,各应用或集群的各节点都需要维护自己的单独缓存,对内存是一种浪费;
2.1.2 分布式缓存
分布式缓存是指缓存与应用本身分离,相比本地缓存来说,很明显的优点是分布式缓存本身就是一个独立的应用或组件,与本地应用隔离,多个应用可共享缓存。
2.2 独立缓存的问题
一般来说,如果系统对于高并发的业务需求并不是很敏感,单机部署时,考虑使用本地缓存即可满足;
常用的本地缓存组件包括:ehcache,caffeine,guawa等,这些都是成熟的方案,在不少互联网项目中都有实践落地经验,可以直接拿来使用;
但本地缓存在分布式部署时一个最大的问题就是缓存一致性的问题,所以在分布式部署模式下,通常考虑使用分布式缓存组件,避免一致性问题;
成熟的分布式缓存组件有:memcached,springcache,jetcache等;
对于一个生产中的应用来说,随着业务数据量的不断增加,独立缓存给应用的架构设计带来了越来越多的挑战,具体来说,表现如下:
2.2.1 缓存雪崩问题
以redis来说,如果对于key的使用不当,很容易出现的一个问题就是缓存雪崩问题,这在高并发的业务场景中是出现过生产事故的,简单来说就是,对于那些高频查询的热点接口缓存数据,,一旦使用不当很容易在某个时间点出现集中失效,造成缓存雪崩。
2.2.2 对宽带压力大
以分布式缓存为例,不管是使用memcached还是redis等存储缓存数据,一旦大量的请求过来查询缓存时,由于缓存是跨机器甚至跨网络,这必然会对当前应用的带宽造成瞬时的冲击。
2.2.3 运行效率低
试想,如果在分布式缓存前面再加上一层本地缓存,即JVM的进程缓存,那么数据到达服务端时,就可以直接从应用进程内部的缓存中获取数据,这比从远端获取redis的缓存效率就更高了。
2.3 多级缓存方案
多级缓存的搭配使用,不仅可以解决上面提到的问题,同时也给架构设计上带来了更多的发挥空间,多级缓存的业务流程如下:
2.3.1 多级缓存实践方案推荐
目前多级缓存在业内经过多年的实践总结,也有不少成熟的方案可供参考,如下提供几种常用的方案提供参考:
caffeine + redis
caffeine 是一款优秀的本地缓存组件,API丰富,灵活度高,而redis就不再过多介绍了,相信不少同学对redis都比较了解。
ehcache + redis
ehcache是一款老牌的本地缓缓组件,经过多年的生产实践,性能可靠、稳定、可配置化参数丰富。
guava-cache + redis
guava是google的一款轻量级的组件,在本地缓存的使用方面性能非常优异,使用成本也很低。
三、jetcache介绍
3.1 jetcache概述
jetcache是阿里开源的基于java开发的缓存框架,支持多种缓存类型:本地缓存、分布式缓存、多级缓存。能够满足不同业务场景的缓存需求。
jetcache具有上手简单、性能高效、拓展性强等特点。支持缓存预热 、缓存key前缀等功能。结合spring-cache使用,可以实现十分优雅的缓存类型切换。
官网地址:GitHub - alibaba/jetcache: JetCache is a Java cache framework.
官方文档:https://github.com/alibaba/jetcache/tree/master/docs/CN
3.2 jetcache 特性
JetCache是由阿里巴巴 Group 开源的一款基于 Spring 和 Redis 的分布式缓存框架。它的主要特点包括:
- 基于注解:通过注解的方式来实现缓存的配置和使用,代码简洁,易于维护;
- 多级缓存:支持多级缓存,可以将数据缓存在本地内存、Redis、Tair、Memcached 等多种缓存存储中,提高缓存的命中率和查询效率;
- 多种缓存协议:支持 Redis、Tair、Memcached 等多种缓存协议,具有良好的可扩展性和兼容性,可以灵活切换缓存存储方式;
- 高性能:JetCache 针对分布式环境下的高并发访问优化了缓存的数据结构和查询算法,提供了较高的性能;
- 易用性:JetCache 的 API 简单易用,支持 Spring 注入和自定义配置,提供了丰富的缓存操作功能,非常适合中小型应用开发;
3.3 jetcache 应用场景
3.3.1 热点数据缓存
JetCache 可以将常用的热点数据缓存在本地或远程缓存中,减少数据库或其他数据源的访问,并提高响应性能和性能稳定性。
相当于是同时融合了本地缓存与分布式缓存,开发者可以根据实际需求选择本地缓存或远程缓存进行配置使用。
3.3.2 多级缓存融合
JetCache 支持多种缓存存储类型,可以将不同的缓存存储类型融合使用,以达到更高的缓存效率和命中率。
在多级缓存中,通常需要多种技术的整合,而引入jetcache之后,可以避免应用中同时引入本地缓存和分布式缓存组件,只需要按照规范开启相关的配置参数即可满足。
3.3.3 支撑高并发读写
JetCache 的缓存算法可以优化高并发读写场景,提高程序性能并降低系统压力。
3.3.4 高速访问查询
JetCache 使用缓存,可以实现高速查询和访问,减少等待时间,并提高用户体验。
3.4 JetCache API使用
3.4.1 缓存管理
JetCache 提供了 CacheBuilder 类来创建缓存,以及 Cache 对象来操作缓存,例如 get、put、remove 等。在调用 Cache 对象的 put 方法时,可以使用注解 @Cache 来设置缓存时间和名称等配置。
3.4.2 注解支持
JetCache 提供了多种注解来实现缓存操作,例如 @Cached,@CacheUpdate, @CacheInvalidate 等。使用注解的方式,可以更加方便地进行缓存操作,例如缓存预热、删除、更新等。
3.4.3 缓存类型
JetCache 支持多种缓存类型,例如本地 memory、Redis、Tair 和 Memcached 等缓存,可以根据业务需求来选择缓存类型。
3.4.4 Spring 集成支持
JetCache 提供了 Spring 集成支持,可以通过注解来注入和配置缓存,简化使用流程。
四、jetcache与springboot整合应用
严格意来说,jetcache并不是一个缓存解决方案,只能说算是一个缓存框架,然后把别的缓存放到jetcache中管理,这样就可以支持AB缓存一起用了。并且jetcache参考了springboot整合缓存的思想,整体技术使用方式和springboot的缓存解决方案思想非常类似。
在正式开始使用jetcache之前需要明确一下,jetcache并不是随便拿两个缓存就能拼接在一起使用,目前jetcache支持的缓存方案中,本地缓存和远程缓存各支持2种类,分别如下:
4.1 缓存支持类型
4.1.1 本地缓存类型
1、LinkedHashMap;
2、Caffieine;
4.1.2 远程缓存支持类型
1、Redis;
2、Tair;
4.2 maven 依赖
下面的依赖为后文案例演示所有需要的基本依赖,如果单独测试jetcache功能,单独引包即可;
java
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--<dependency>
<groupId>com.alicp.jetcache</groupId>
<artifactId>jetcache-starter-redis</artifactId>
<version>2.6.2</version>
</dependency>-->
<dependency>
<groupId>com.alicp.jetcache</groupId>
<artifactId>jetcache-starter-redis</artifactId>
<version>2.5.11</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
</dependencies>
4.3 本地缓存方案
4.3.1 application 配置文件
可以参考git文档进行相关参数配置,下面为基本的配置文件
java
jetcache:
statIntervalMinutes: 1 #每过1分钟在控制台汇总一次数据
areaInCacheName: false
local:
default:
type: linkedhashmap #可选值:caffeine/linkedhashmap
keyConvertor: fastjson #可选值 :fastjson/jackson
limit: 100 #本地缓存限制的最大个数
4.3.2 新增测试方法
在业务层新增一个查询方法,关于方法上面使用的注解,和springcache上面的很像,有兴趣的同学可以参阅官网文档或相关资料深入了解,在日常开发中,掌握基本的注解参数使用即可,这里需要说明的是,使用本地缓存最关键的地方是注解中的,cacheType这个属性,通过指定CacheType的类型就可以指定是使用本地缓存?远程缓存?还是两种缓存同时使用。
java
@Cached(name="book_",key="#id",expire = 3600,cacheType = CacheType.LOCAL)
public Book getById(Integer id) {
System.out.println("初次查询走缓存");
Book book = new Book();
book.setId(id);
book.setName("Java全栈工程师");
book.setDescription("最新上市");
return book;
}
4.3.3 新增测试接口
在控制器层增加一个查询接口如下
java
//http://localhost:8083/book/getById?id=100
@GetMapping("/getById")
public Book getById(int id){
return bookService.getById(id);
}
4.3.4 启动类
启动类上需要添加下面的这个注解:EnableCreateCacheAnnotation,表示扫描的包路径下的方法上使用了缓存注解将会生效;
java
@SpringBootApplication
@EnableMethodCache(basePackages = "com.congge.service")
@EnableCreateCacheAnnotation
public class JetApp {
public static void main(String[] args) {
SpringApplication.run(JetApp.class,args);
}
}
4.3.5 效果测试
启动工程,然后调用接口,第一次调用可以看到控制台输出了下面的日志;
同时接口也返回结果
再次调用接口时,由于缓存尚未失效,可以看到控制台并没有输出日志,而是直接返回了数据;
4.4 远程缓存方案
4.4.1 application 添加如下配置
主要关注remote开头的那部分
java
jetcache:
statIntervalMinutes: 1 #每过1分钟在控制台汇总一次数据
areaInCacheName: false
local:
default:
type: linkedhashmap
keyConvertor: fastjson
limit: 100
#远程缓存配置
remote:
default:
type: redis
host: localhost
port: 6379
keyConvertor: fastjson #fastjson2 #other choose:fastjson/jackson
valueEncoder: java #other choose:kryo/kryo5
valueDecoder: java #other choose:kryo/kryo5
poolConfig:
maxTotal: 50
minIdle: 5
maxIdle: 20
4.4.2 修改业务层方法注解参数
只需修改注解中的属性cacheType为REMOTE即可;
java
@Cached(name="book_",key="#id",expire = 3600,cacheType = CacheType.REMOTE)
public Book getById(Integer id) {
System.out.println("初次查询走缓存");
Book book = new Book();
book.setId(id);
book.setName("Java全栈工程师");
book.setDescription("最新上市");
return book;
}
4.4.3 启动服务测试效果
启动redis,启动工程后,调用相同的接口,第一次调用效果如下
再次调用时控制台就没有输出日志了
同时可以到redis中看一下缓存的数据
4.4.4 字段级缓存@CreateCache
在jetcache中存在缓存空间的概念,可以类比命名空间namespace的概念,好处就是可以清晰的区分出不同的业务在不同的缓存空间中进行分类管理,在jetcache中对应为字段级缓存,注解标签为:@CreateCache,注解常用的属性如下:
属性 | 默认值 | 备注说明 |
---|---|---|
name | 无 | 指定缓存的名称,不是必须的,如果没有指定,会使用类名+方法名。name会被用于远程缓存的key前缀。另外在统计中,一个简短有意义的名字会提高可读性。如果两个@CreateCache 的name 和area 相同,它们会指向同一个Cache 实例 |
expire | 无 | 该Cache实例的默认超时时间定义,注解上没有定义的时候会使用全局配置,如果此时全局配置也没有定义,则取无穷大 |
timeUnit | TimeUnit.SECONDS | 指定expire的单位 |
cacheType | CacheType.REMOTE | 缓存的类型,包括CacheType.REMOTE、CacheType.LOCAL、CacheType.BOTH。如果定义为BOTH,会使用LOCAL和REMOTE组合成两级缓存 |
用法示例:
如下配置文件中,在与default平级的一栏增加一个book打头的配置去,其他的配置和上面保持一致;
java
server:
port: 8087
jetcache:
statIntervalMinutes: 1 #每过1分钟在控制台汇总一次数据
areaInCacheName: false
local:
default:
type: linkedhashmap
keyConvertor: fastjson
limit: 100
remote:
default:
type: redis
host: localhost
port: 6379
keyConvertor: fastjson
valueEncoder: java
valueDecoder: java
poolConfig:
maxTotal: 50
minIdle: 5
maxIdle: 20
#具体某个命名空间下的配置
user:
type: redis
host: localhost
port: 6379
keyConvertor: fastjson
valueEncoder: java
valueDecoder: java
poolConfig:
maxTotal: 50
minIdle: 5
maxIdle: 20
为当前的业务类注入Cache属性,并指定area的属性值为user,说明当前的缓存将归在user缓存空间下
java
@Service
public class UserService {
@CreateCache(area = "user",name="jetCache:",expire = 3600,cacheType= CacheType.REMOTE)
private Cache<Long,User> jetCache;
//@Cached(name = "userCache:", key = "#id", expire = 1800, cacheType = CacheType.LOCAL)
public User getById(Long id) {
if(jetCache != null && jetCache.get(id) != null){
System.out.println("从缓存直接返回数据");
return jetCache.get(id);
}
System.out.println("初次查询未走缓存");
User user = new User();
user.setId(100L);
user.setName("mike");
jetCache.put(id,user);
return user;
}
}
然后按照同样的方式调用一下接口,并观察控制台输出日志
4.5 同时开启本地缓存和远程缓存
4.5.1 修改配置属性值
基于上一步的基础上只需要将查询方法中的注解中属性值修改为 : cacheType = CacheType.BOTH 即可;
java
@Cached(name="book_",key="#id",expire = 3600,cacheType = CacheType.BOTH)
public Book getById(Integer id) {
System.out.println("初次查询走缓存");
Book book = new Book();
book.setId(id);
book.setName("Java全栈工程师");
book.setDescription("最新上市");
return book;
}
4.5.2 业务层其他方法
下面给出业务实现类中涉及到缓存相关的其他注解
java
@Service
public class BookService {
@Cached(name="book_",key="#id",expire = 3600,cacheType = CacheType.BOTH)
public Book getById(Integer id) {
System.out.println("初次查询走缓存");
Book book = new Book();
book.setId(id);
book.setName("Java全栈工程师");
book.setDescription("最新上市");
return book;
}
@CacheUpdate(name="book_",key="#book.id",value="#book")
public boolean update(Book book) {
System.out.println("修改数据,同时更新缓存");
book.setName("最新Python教程");
return true;
}
@CacheInvalidate(name="book_",key = "#id")
public boolean delete(Integer id) {
System.out.println("删除书籍,同时删除缓存");
return true;
}
/*@Cached(name="book_",key="#id",expire = 3600,cacheType = CacheType.REMOTE)
@CacheRefresh(refresh = 5)
public Book getById(Integer id) {
return bookDao.selectById(id);
}
*/
}
4.6 jetcache 核心注解
JetCache方法缓存和SpringCache比较类似,它原生提供了TTL支持,以保证最终一致,并且支持二级缓存。JetCache2.4以后支持基于注解的缓存更新和删除。在spring环境下,使用@Cached注解可以为一个方法添加缓存,@CacheUpdate用于更新缓存,@CacheInvalidate用于移除缓存元素。注解可以加在接口上也可以加在类上,加注解的类必须是一个spring bean。
4.6.1 @Cached注解
该注解主要用作查询业务中缓存查询数据,具体来说包括:
- 在方法上添加 @Cached 注解,指定缓存的 key 和过期时间等参数;
- 当方法被调用时,JetCache 会先从缓存中查找对应的数据;
- 如果缓存中存在数据,则直接返回缓存中的数据,不再执行方法体;
- 如果缓存中不存在数据,则执行方法体,并将方法的返回值存入缓存中;
- 后续调用该方法时,将直接从缓存中获取数据,不再执行方法体;
- 缓存的过期时间到达后,缓存数据将被自动清除,下次调用该方法将重新执行方法体并更新缓存数据;
JetCache 支持多种缓存类型,包括本地内存缓存、Redis 缓存、Caffeine 缓存等,可以根据实际需求进行配置。同时,JetCache 还提供了缓存预热、缓存穿透、缓存雪崩等解决方案,以提高缓存的效率和稳定性。
@Cached注解和@CreateCache的属性非常类似,但是多几个:
属性 | 默认值 | 备注 |
---|---|---|
area | "default" | 如果在配置中配置了多个缓存area,在这里指定使用哪个area |
name | 无 | 指定缓存的唯一名称,不是必须的,如果没有指定,会使用类名+方法名。name会被用于远程缓存的key前缀。另外在统计中,一个简短有意义的名字会提高可读性。 |
key | 无 | 使用SpEL指定key,如果没有指定会根据所有参数自动生成。 |
expire | 无 | 超时时间。如果注解上没有定义,会使用全局配置,如果此时全局配置也没有定义,则为无穷大 |
timeUnit | TimeUnit.SECONDS | 指定expire的单位 |
cacheType | CacheType.REMOTE | 缓存的类型,包括CacheType.REMOTE、CacheType.LOCAL、CacheType.BOTH。如果定义为BOTH,会使用LOCAL和REMOTE组合成两级缓存 |
localLimit | 无 | 1、如果cacheType为LOCAL或BOTH,这个参数指定本地缓存的最大元素数量,以控制内存占用; 2、如果注解上没有定义,会使用全局配置,如果此时全局配置也没有定义,则为100,参数 localLimit 表示本地缓存的最大条目限制; 3、当使用 JetCache 的本地缓存功能时,localLimit 参数可以控制本地缓存中最多缓存的条目数量,如果超过了这个数量,将会按照 LRU(Least Recently Used)算法删除最近最少使用的缓存条目,以保持缓存的大小在限制范围内; 4、localLimit 默认值为 100条,可以通过设置该值来优化缓存性能和内存使用; 5、当type为LOCAL时,配置localLimit,当key值超出限制条件,会删除最少使用的条目,重新请求缓存过的,会走到db再缓存一次; 6、当type为BOTH时,虽然配置了localLimit 当key值超出限制条件,本地会删除使用最少得条目,但是远程还有缓存,查询缓存时是优先查询本地,没有再去远程,都没有再走db,将查询结果进行一次缓存; 7、如果配置BOTH时,可以配置该项减少本地内存使用,但是不影响缓存整体使用因为有远程兜底; |
localExpire | 无 | 仅当cacheType为BOTH时适用,为内存中的Cache指定一个不一样的超时时间,通常应该小于expire |
serialPolicy | 未定义 | 指定远程缓存的序列化方式。可选值为SerialPolicy.JAVA和SerialPolicy.KRYO。如果注解上没有定义,会使用全局配置,如果此时全局配置也没有定义,则为SerialPolicy.JAVA |
keyConvertor | 无 | 指定KEY的转换方式,用于将复杂的KEY类型转换为缓存实现可以接受的类型,当前支持KeyConvertor.FASTJSON和KeyConvertor.NONE。NONE表示不转换,FASTJSON可以将复杂对象KEY转换成String。如果注解上没有定义,会使用全局配置。 |
enabled | true | 是否激活缓存。例如某个dao方法上加缓存注解,由于某些调用场景下不能有缓存,所以可以设置enabled为false,正常调用不会使用缓存,在需要的地方可使用CacheContext.enableCache在回调中激活缓存,缓存激活的标记在ThreadLocal上,该标记被设置后,所有enable=false的缓存都被激活。 |
cacheNullValue | false | 当方法返回值为null的时候是否要缓存 |
condition | 无 | 使用SpEL指定条件,如果表达式返回true的时候才去缓存中查询 |
postCondition | 无 | 使用SpEL指定条件,如果表达式返回true的时候才更新缓存,该评估在方法执行后进行,因此可以访问到#result |
4.6.2 @CacheUpdate注解
该注解常用于方法的修改,用户更新缓存数据
属性 | 默认值 | 备注 |
---|---|---|
area | "default" | 如果在配置中配置了多个缓存area,在这里指定使用哪个area,指向对应的@Cached定义。 |
name | 无 | 指定缓存的唯一名称,指向对应的@Cached定义。 |
key | 无 | 使用SpEL指定key |
value | 无 | 使用SpEL指定value |
condition | 无 | 使用SpEL指定条件,如果表达式返回true才执行更新,可访问方法结果#result |
4.6.3 @CacheInvalidate注解
该注解用于删除方法中让缓存失效
属性 | 默认值 | 备注 |
---|---|---|
area | "default" | 如果在配置中配置了多个缓存area,在这里指定使用哪个area,指向对应的@Cached定义。 |
name | 无 | 指定缓存的唯一名称,指向对应的@Cached定义。 |
key | 无 | 使用SpEL指定key |
condition | 无 | 使用SpEL指定条件,如果表达式返回true才执行删除,可访问方法结果#result |
4.6.4 @CacheRefresh注解
该注解用于强制刷新缓存,即便缓存还未到达失效时间
属性 | 默认值 | 备注 |
---|---|---|
refresh | 无 | 刷新间隔 |
timeUnit | TimeUnit.SECONDS | 时间单位 |
stopRefreshAfterLastAccess | 无 | 指定该key多长时间没有访问就停止刷新,如果不指定会一直刷新 |
refreshLockTimeout | 60秒 | 类型为BOTH/REMOTE的缓存刷新时,同时只会有一台服务器在刷新,这台服务器会在远程缓存放置一个分布式锁,此配置指定该锁的超时时间 |
4.6.5 @CachePenetrationProtect注解
当缓存访问未命中的情况下,对并发进行的加载行为进行保护。 当前版本实现的是单JVM内的保护,即同一个JVM中同一个key只有一个线程去加载,其它线程等待结果。
对于以上未定义默认值的参数,如果没有指定,将使用yml中指定的全局配置,全局配置请参考配置说明
4.7 jetcache使用总结
关于jetcache的使用,结合实际经验做如下几点总结:
- JetCache 适用于标准的查询单条数据或者查询列表数据的接口进行完整的缓存,这就要求接口的入参必须包含唯一健,且返回值必须是DTO对象。同时对于分页查询的接口无法实现缓存,也没有意义;
- JetCache 默认使用的是 JDK 提供的序列化,JDK序列化性能差,可读性差。在目前项目开发过程中,一般 Redis 缓存都使用 JSON 格式对 Value 进行序列化;
- JetCache 最大的优势是实现了本地和远程的二级缓存,相较于使用 Redis 缓存,使用本地缓存能够提供更高的吞吐量;
- 注意数据进入远程缓存时的类型转换问题;
- jetcache提供有简单的缓存信息命中报表方便开发者即时监控缓存数据命中情况;
五、写在文末
jetcache的出现让开发者减少并降低了在使用二级缓存时的复杂性和难度,同时也给架构设计带了更多的可拓展性,一种新的技术组件的出现要么是提高解决问题的效率,要么是为程序设计带来更多便捷性的思路,这一点或许就是做中间件或SDK的妙处,本篇到此结束,感谢观看。