解析springboot整合谷歌开源缓存框架Guava Cache原理
作者:sjgeng111 发布时间:2023-11-07 13:24:23
Guava Cache:⾕歌开源缓存框架
Guava Cache是在内存中缓存数据,相比较于数据库或redis存储,访问内存中的数据会更加高效。Guava官网介绍,下面的这几种情况可以考虑使用Guava Cache:
愿意消耗一些内存空间来提升速度。
预料到某些键会被多次查询。
缓存中存放的数据总量不会超出内存容量。
github地址:https://github.com/google/guava/wiki/CachesExplained
全内存的本地缓存实现,查询数据时先根据自定义索引判断Guava Cache中是否存在该数据,如果存在就从Guava Cache中取,不存在就从数据库中查询,再保存到Guava Cache中,减少数据库查询的压力
⾼性能且功能丰富
线程安全,操作简单 (底层实现机制类似ConcurrentMap)
Guava Cache使用
添加依赖
<!--guava依赖包-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
</dependency>
封装api工具类:
@Component
public class BaseCache {
private Cache<String,Object> tenMinuteCache = CacheBuilder.newBuilder()
//设置缓存初始大小,应该合理设置,后续会扩容
.initialCapacity(10)
//最大值
.maximumSize(100)
//并发数设置
.concurrencyLevel(5)
//缓存过期时间,写入后10分钟过期
.expireAfterWrite(600,TimeUnit.SECONDS)
//统计缓存命中率
.recordStats()
.build();
private Cache<String,Object> oneHourCache = CacheBuilder.newBuilder()
//设置缓存初始大小,应该合理设置,后续会扩容
.initialCapacity(30)
//最大值
.maximumSize(100)
//并发数设置
.concurrencyLevel(5)
//缓存过期时间,写入后1小时 过期
.expireAfterWrite(3600,TimeUnit.SECONDS)
//统计缓存命中率
.recordStats()
.build();
public Cache<String, Object> getOneHourCache() {
return oneHourCache;
}
public void setOneHourCache(Cache<String, Object> oneHourCache) {
this.oneHourCache = oneHourCache;
}
public Cache<String, Object> getTenMinuteCache() {
return tenMinuteCache;
}
public void setTenMinuteCache(Cache<String, Object> tenMinuteCache) {
this.tenMinuteCache = tenMinuteCache;
}
}
实际开发中使用:(查询数据时先根据自定义索引判断Guava Cache中是否存在该数据,如果存在就从Guava Cache中取,不存在就从数据库中查询,再保存到Guava Cache中)
自定义索引:
/**
* 缓存key管理类
*/
public class CacheKeyManager {
/**
* 首页轮播图缓存key
*/
public static final String INDEX_BANNER_KEY = "index:banner:list";
/**
* 首页视频列表缓存key
*/
public static final String INDEX_VIDEL_LIST = "index:video:list";
/**
* 视频详情缓存key, %s是视频id
*/
public static final String VIDEO_DETAIL = "video:detail:%s";
}
如果存在就从Guava Cache中取,不存在就从数据库中查询,再保存到Guava Cache中
@Service
public class VideoServiceImpl implements VideoService {
@Autowired
private VideoMapper videoMapper;
@Autowired
private BaseCache baseCache;
@Override
public List<Video> listVideo() {
try{
Object cacheObj = baseCache.getTenMinuteCache().get(CacheKeyManager.INDEX_VIDEL_LIST,()->{
List<Video> videoList = videoMapper.listVideo();
return videoList;
});
if(cacheObj instanceof List){
List<Video> videoList = (List<Video>)cacheObj;
return videoList;
}
}catch (Exception e){
e.printStackTrace();
}
//可以返回兜底数据,业务系统降级-》SpringCloud专题课程
return null;
}
@Override
publc List<VideoBanner> listBanner() {
try{
Object cacheObj = baseCache.getTenMinuteCache().get(CacheKeyManager.INDEX_BANNER_KEY, ()->{
List<VideoBanner> bannerList = videoMapper.listVideoBanner();
System.out.println("从数据库里面找轮播图列表");
return bannerList;
});
if(cacheObj instanceof List){
List<VideoBanner> bannerList = (List<VideoBanner>)cacheObj;
return bannerList;
}
}catch (Exception e){
e.printStackTrace();
}
return null;
}
@Override
public Video findDetailById(int videoId) {
//单独构建一个缓存key,每个视频的key是不一样的
String videoCacheKey = String.format(CacheKeyManager.VIDEO_DETAIL,videoId);
try{
Object cacheObject = baseCache.getOneHourCache().get( videoCacheKey, ()->{
// 需要使用mybaits关联复杂查询
Video video = videoMapper.findDetailById(videoId);
return video;
});
if(cacheObject instanceof Video){
Video video = (Video)cacheObject;
return video;
}
}catch (Exception e){
e.printStackTrace();
}
return null;
}
}
使用压测⼯具Jmeter5.x进行接口压力测试:
压测⼯具本地快速安装Jmeter5.x
简介:GUI图形界⾯的安装 Jmeter5.x
需要安装JDK8 以上
建议安装JDK环境,虽然JRE也可以,但是压测https需要JDK⾥⾯的 keytool⼯具
快速下载:https://jmeter.apache.org/download_jmeter.cgi
⽂档地址:http://jmeter.apache.org/usermanual/get-started.html
解jmeter解压⽂件⾥⾯的各个⽬录:
bin:核⼼可执⾏⽂件,包含配置
jmeter.bat: windows启动⽂件(window系统⼀定要配置显示⽂件拓展名)
jmeter: mac或者linux启动⽂件
jmeter-server:mac或者Liunx分布式压测使⽤的启动⽂件
jmeter-server.bat:window分布式压测使⽤的启动⽂件
jmeter.properties: 核⼼配置⽂件
extras:插件拓展的包
lib:核⼼的依赖包
Jmeter语⾔版本中英⽂切换
控制台修改 menu -> options -> choose language
配置⽂件修改
bin⽬录 -> jmeter.properties
默认 #language=en
改为 language=zh_CN
新增聚合报告:线程组->添加-> * ->聚合报告(Aggregate Report)
lable: sampler的名称
Samples: ⼀共发出去多少请求,例如10个⽤户,循环10次,则是 100
Average: 平均响应时间
Median: 中位数,也就是 50% ⽤户的响应时间
90% Line : 90% ⽤户的响应不会超过该时间 (90% of the samples took no more than
this time. The remaining samples at least as long as this)
95% Line : 95% ⽤户的响应不会超过该时间
99% Line : 99% ⽤户的响应不会超过该时间
min : 最⼩响应时间
max : 最⼤响应时间
Error%:错误的请求的数量/请求的总数
Throughput: 吞吐量——默认情况下表示每秒完成的请求数(Request per Second) 可类⽐为
qps、tps
KB/Sec: 每秒接收数据量
启⽤缓存 压测热点数据接接⼝Throughput: 14000:
不启⽤缓存 压测热点数据接⼝
视频轮播图接⼝ Throughput : 2700
当数据访问量较大时,比如主页信息等,可以考虑使用Guava Cache,可以将程序频繁用到的少量数据存储到Guava Cache中,以改善程序性能!
来源:https://blog.csdn.net/sjgllllll/article/details/119709624


猜你喜欢
- 在Java的学习中,涉及到两个系统环境变量path和classpath一. path环境变量path环境变量是系统环境变量的一种,它用于保存
- 定义在一幅无向图G=(V,E) 中,(u,v) 为连接顶点u和顶点v的边,w(u,v)为边的权重,若存在边的子集T&am
- 一、简介CyclicBarrier 字面意思回环栅栏(循环屏障),它可以实现让一组线程等待至某个状态(屏障点)之后再全部同时执行。叫做回环是
- java实现拖拽示例Swing中实现拖拽功能,代码很简单,都有注释,自己看,运行效果如下图:package com;import java.
- C# 中闭包(Closure)详解这个问题是在最近一次英格兰 Brighton ALT.NET Beers 活动中提出来的。我发现,如果不用
- 前面一篇文章我们介绍了使用CAS算法实现的非阻塞队列ConcurrentLinedQueue, 下面我们来介绍使用独占锁实现的阻塞队列Lin
- 如题,市面上常见的方法是:var handle = bmp.GetHicon(); //得到图标句柄return Icon.Fr
- 包含不重复元素的集合称为“集(set)”。.NET Framework包含两个集HashSet<
- 这篇文章主要介绍了JAVA使用 * 对象进行敏感字过滤代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值
- 一、案例一//XML文件写方法 //编写XML文件的格式并存储到指定的FilePath
- 目录1. 应用场景1.1. 保障线程安全1.2. 显示传递参数2. 实现原理3. 注意事项ThreadLocal是线程私有的局部变量存储容器
- 先给大家看下效果图:MenuPopwindow:package com.cloudeye.android.cloudeye.view;imp
- 前言spring中解析元素最重要的一个对象应该就属于 BeanDefinition了;这个Spring容器中最基本的内部数据结构;它让xml
- 1. 将一些需要变动的配置写在属性文件中比如,没有把一些需要并发执行时使用的线程数设置成可在属性文件中配置。那么你的程序无论在DEV环境中,
- ArrrayList是Java中经常被用到的集合,弄清楚它的底层实现,有利于我们更好地使用它。下图是ArrayList的UML图从图中我们可
- Settings是WebView提供给上层App的一个配置Webview的接口,每个WebView都有一个WebSettings,要控制We
- 从相册或拍照更换图片功能的实现:(取图无裁剪功能)获取图片方式: (类似更换头像的效果)1、手机拍照 选择图片;2、相册选取图片;本文只是简
- 上一次自己写了一个多线程断点续传下载的demo,过于麻烦,bug超多,所以我学习使用xutils来完成此功能。先将xutils依赖搭建好(上
- 好久没有写有关UI的博客了,刚刚翻了一下之前的博客,最近一篇有关UI的博客:Android UI设计系列之自定义Dialog实现各种风格的对
- 环境搭建项目结构图:1.我们首先做好服务端pom.xml<dependencies>