前言
在项目开发中,为提升系统性能,减少数据库服务器压力,通常会用到缓存。而合理的使本地内存缓存和远程缓存可以降低Cache Server的压力以及我们提供的服务的响应时间。本文将介绍如何使用 JetCache 框架简单优雅地实现多级缓存。
一、JetCache简介
JetCache 是一个基于Java的缓存系统封装,提供统一的API和注解来简化缓存的使用。 JetCache 提供了比 SpringCache 更加强大的注解,可以原生的支持TTL、两级缓存、分布式自动刷新,还提供了 Cache
接口用于手工缓存操作。
当前有四个实现, RedisCache
、 TairCache
(此部分未在github开源)、 CaffeineCache
(in memory) 和一个简易的 LinkedHashMapCache
(in memory),要添加新的实现也是非常简单的。
全部特性:
- 通过统一的API访问Cache系统
- 通过注解实现声明式的方法缓存,支持TTL和两级缓存
- 通过注解创建并配置Cache实例
- 针对所有Cache实例和方法缓存的自动统计
- Key的生成策略和Value的序列化策略是可以配置的
- 分布式缓存自动刷新,分布式锁 (2.2+)
- 异步Cache API (2.2+,使用Redis的lettuce客户端时)
- Spring Boot支持
二、JetCache用法
1.Method cache
1.缓存基本用法:声明方法上加上 @Cached
、 @CacheUpdate
、 @CacheInvalidate
注解
name
指定缓存的唯一名称,不是必须的,如果没有指定,会使用类名+方法名。name会被用于远程缓存的key前缀。另外在统计中,一个简短有意义的名字会提高可读性。key
使用SpEL指定key,如果没有指定会根据所有参数自动生成。value
使用SpEL指定value,注意REMOTE类型缓存的实体对象需要序列化(User implements Serializable),否则无法缓存到REMOTE。expire
超时时间。如果注解上没有定义,会使用全局配置,如果此时全局配置也没有定义,则为无穷大。cacheType
缓存的类型,包括CacheType.REMOTE、CacheType.LOCAL、CacheType.BOTH。如果定义为BOTH,会使用LOCAL和REMOTE组合成两级缓存。
1 | public interface UserService { |
2.自动刷新和加载保护缓存: 声明方法上加上 @CacheRefresh
和 @CachePenetrationProtect
注解
自动刷新和加载保护是JetCache的大杀器,对于加载开销比较大的对象,为了防止缓存未命中时的高并发访问打爆数据库
refresh
刷新间隔timeUnit
时间单位stopRefreshAfterLastAccess
指定该key多长时间没有访问就停止刷新,如果不指定会一直刷新1
2
3
4
5
6public interface SummaryService{
BigDecimal summaryOfToday(long categoryId);
}cacheType
为REMOTE或者BOTH的时候,刷新行为是全局唯一的,也就是说,即使应用服务器是一个集群,也不会出现多个服务器同时去刷新一个key的情况。@CachePenetrationProtect
注解保证当缓存未命中的时候,一个JVM里面只有一个线程去执行方法,其它线程等待结果。 一个key的刷新任务,自该key首次被访问后初始化,如果该key长时间不被访问,在stopRefreshAfterLastAccess
指定的时间后,相关的刷新任务就会被自动移除,这样就避免了浪费资源去进行没有意义的刷新。
更多 Method cache 详细用法可以参考MethodCache文档
2.Cache API
加在方法上的注解毕竟不能提供最灵活的控制,所以JetCache提供了Cache API,使用起来就像Map一样:
1.先使用CacheManager创建Cache实例:
1 |
|
2.使用 Cache API
1 | UserDO user = userCache.get(12345L); |
更多 Cache API 详细用法可以参考Cache API文档
3.Advanced API
1.Cache接口支持异步:
1 | CacheGetResult r = cache.GET(userId); |
2.实现不严格的分布式锁:
1 | cache.tryLockAndRun("key", 60, TimeUnit.SECONDS, () -> heavyDatabaseOperation()); |
更多 Advanced API 详细用法可以参考Advanced API文档
三、JetCache实践
代码实践主要用了 @Cache
注解和自定义 CacheManager
的两种方式实现缓存
1.Maven pom
1 |
|
1.Entity
1 | package com.xxx.mp.entity; |
2.Controller
1 | package com.xxx.mp.controller; |
3.Service
1 | package com.xxx.mp.service; |
1 | package com.xxx.mp.service; |
1 | package com.xxx.mp.mapper; |
4.Config
启动类
1 | package com.xxx.mp; |
application.yml配置
1 | # 服务器配置 |
5.sql-script
数据库脚本
1 | #创建用户表 |
6.UnitTest
接口单元测试
1 | package com.xxx.mp; |
7.http-request
1 | ### 查询用户信息-local |
参考文献
1.缓存之王Caffeine Cache,性能比Guava更强
2.阿里巴巴开源的通用缓存访问框架JetCache介绍
3.jetcache:阿里这款多级缓存框架一定要掌握
- 本文作者: yinshuang
- 本文链接: https://yinshuang007.github.io/2023/08/12/阿里缓存框架Jetcache实践/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!