1 介绍
是阿里的双极缓存,jvm-->redis-->数据库
文档:jetcache/docs/CN at master · alibaba/jetcache · GitHub
2 注意事项
- 使用的实体类一定实现序列化接口
- 定时刷新注解,慎用 它会为每一个key创建一个定时器 :场景为:key少,访问量大
- 注解泛型一定和方法泛型保持一致,否则报错。
-
expire:过期时间设置为-1或者不设置 过期时间68年左右。
-
put入参key是null不会存数据,get入参为null,会报空指针。空字符串没有任务问题。使用缓存时我们要多封装一层,判断key为空时情况
- 版本
3 总结
缓存类型为BOTH时:
查询流程:
单机:本地缓存默认是100条数据(初始化数据时,留后查询的数据),redis留所有数据。本地缓存查询不到时,去redis找,保存到本地缓存,同时也去除一条本地缓存数据。
集群:第一次访问服务器A时,流程同上述一样,第二次访问服务器B时,直接去redis找,保存到本地缓存。
删除api:本地和redis都会删除数据
4 实战
4.1 pom
org.projectlombok lombok1.18.30 com.alicp.jetcache jetcache-starter-redis2.7.0 redis.clients jedis4.3.1 com.alibaba fastjson1.2.83
4.2 启动类:
@EnableMethodCache(basePackages="com.example.jetcache.mapper") //如果不用@CreateCache注解可以删除 EnableCreateCacheAnnotation @EnableCreateCacheAnnotation
4.3 配置文件
jetcache: ## 统计间隔,默认值0,0表示不统计,开启后定期在控制台输出缓存信息 statIntervalMinutes: 15 ## 默认值false, 是否将 areaName 作为远程缓存key前缀 areaInCacheName: false ## 本地缓存配置 local: default: ## default表示全部生效,也可以指定某个cacheName ## 本地缓存类型,其他可选:caffeine/linkedhashmap type: caffeine # 指定KEY的转换方式, 可选 fastjson2,fastjson,jackson keyConvertor: fastjson ## 远程缓存配置 remote: default: ## default表示全部生效,也可以指定某个cacheName type: redis ## key转换器方式n keyConvertor: fastjson broadcastChannel: projectA ## redis序列化方式 valueEncoder: java valueDecoder: java ## redis线程池 poolConfig: minIdle: 5 maxIdle: 20 maxTotal: 50 ## redis地址与端口 host: 127.0.0.1 port: 6379
4.4 基础查询/删除/更新/定时刷新(慎用)
import com.alicp.jetcache.anno.*; import com.example.jetcache.entity.User; import org.apache.ibatis.annotations.Mapper; import java.util.List; import java.util.concurrent.TimeUnit; @Mapper public interface UserMapper { ListqueryUserAll(); List queryUser(User user); /** * BOTH类型查询 * expire 过期时间,redis和本地缓存一致 * 重启服务,本地jvm消失,会先查询redis,然后存入本地缓存 * 本地缓存存在,不会查询redis * * * @param id * @return */ @Cached(name="userCache:", key="#id", expire = 15 ,cacheType = CacheType.BOTH) /** * 只要是查询过的数据,就会定时刷新,从未查询过,则无定时刷新 * refresh: 定时器执行查询间隔时间-每过36秒就会执行一次定时器 * stopRefreshAfterLastAccess: 表示多久不使用对应的key缓存则会停止刷新。,如果不指定会一直刷新 refreshLockTimeout:类型为BOTH/REMOTE的缓存刷新时,同时只会有一台服务器在刷新,这台服务器会在远程缓存放置一个分布式锁,此配置指定该锁的超时时间 */ @CacheRefresh(refresh = 36, stopRefreshAfterLastAccess = 3600, timeUnit = TimeUnit.SECONDS) /** * 注解作用——当缓存访问【未命中】的情况下,对并发进行的加载行为进行保护;当前版本实现的是单JVM内的保护,即同一个JVM中同一个key只有一个线程去加载,其它线程等待结果 */ @CachePenetrationProtect List queryUserById(String id); /** * 删除 * @param id * @return */ @CacheInvalidate(name="userCache.", key="#id") int delById(int id); @CacheUpdate(name="userCache.", key="#user.id", value="#user") int save(User user); }
4.5 CreateCache
//无则新增,有则覆盖
userCache.put(id,users);
//删除
userCache.remove(id);
//删除所有数据暂无api
方式一:废弃了
@CreateCache(name= "userCache:", expire = 3600,cacheType = CacheType.BOTH) private Cache> userCache; @PostMapping(value = "/queryUserById") public List queryUserById(@RequestParam String id) { if(CollectionUtil.isNotEmpty(userCache.get(id) )){ return userCache.get(id); } List users = userMapper.queryUserById(id); //无则新增,有则覆盖 userCache.put(id,users); return users; }
方式二:spring注入直接使用,如上图使用API
@Autowired
private Cache
userCache;
@Configuration public class JetCacheConfig { @Autowired private CacheManager cacheManager; private Cache> userCache; @Resource(name = "userMapper") private UserMapper userMapper; @PostConstruct public void init(){ QuickConfig qc = QuickConfig.newBuilder("userCache:") .expire(Duration.ofSeconds(3600)) .cacheType(CacheType.BOTH) //true 集群模式下,任何本地缓存都会强制删除缓存,fasle,则请求到哪个服务,哪个服务删除本地缓存,其他服务本地缓存保持不变 // 本地缓存更新后,将在所有的节点中删除缓存,以保持强一致性 // 两级缓存的情况下,缓存更新时发消息让其它JVM实例中的缓存失效,需要配置broadcastChannel才生效 .syncLocal(true) // 默认100 后面数据会挤掉前面的数据 本地缓存元素个数限制,只对CacheType.LOCAL和CacheType.BOTH有效 .localLimit(100) //不存在时则执行这个方法 .loader(this::loadOrderSumFromDatabase) //newPolicy: 定时器执行查询间隔时间 // stopRefreshAfterLastAccess:表示多久不使用对应的key缓存则会停止刷新。 // .refreshPolicy(RefreshPolicy.newPolicy(6, TimeUnit.SECONDS).stopRefreshAfterLastAccess(10, TimeUnit.SECONDS)) //cache穿透保护注释表示缓存将在多线程环境中同步加载。 .penetrationProtect(true) .build(); userCache = cacheManager.getOrCreateCache(qc); //查询数据库,初始化全部数据 // userCache.putAll(); } private List loadOrderSumFromDatabase(String id) { return userMapper.queryUserById(id); } @Bean public Cache > getUserCache(){ return userCache; } }
还没有评论,来说两句吧...