Guava Cache
分布式缓存和本地缓存知识
-
什么是缓存
- 程序经常要调用的对象存在内存中,方便其使用时可以快速调用,不必去数据库或者其他持久化设备中查询,主要就是提高性能
- DNS 缓存、前端缓存、代理服务器缓存 Nginx、应用程序缓存(本地缓存、分布式缓存)、数据库缓存
-
分布式缓存
- 与应用分离的缓存组件或服务,与本地应用隔离一个独立的应用,多个应用可直接的共享缓存
- 常见的分布式缓存 Redis、Memcached 等
-
本地缓存
- 和业务程序一起的缓存,例如 myabtis 的一级或者二级缓存,本地缓存自然是最快的,但是不能在多个节点共享
- 常见的本地缓存:ssm 基础课程 myabtis 一级缓存、MyBatis 二级缓存;框架本身的缓存; Redis 本地单机服务;ehchche;guava cache、Caffeine 等
-
选择本地缓存和分布式缓存
- 和业务数据结合去选择
- 高并发项目里面一般都是有本地缓存和分布式缓存共同存在的
Guava Cache
- GitHub 地址:https://github.com/google/guava/wiki/CachesExplained
- 全内存的本地缓存实现
- 高性能且功能丰富
- 线程安全,操作简单 (底层实现机制类似 ConcurrentMap)
添加依赖
1 <!--guava依赖包-->
2 <dependency>
3 <groupId>com.google.guava</groupId>
4 <artifactId>guava</artifactId>
5 <version>19.0</version>
6 </dependency>
封装 API
src/main/java/net/xdclass/online_xdclass/utils/BaseCache.java
1package net.xdclass.online_xdclass.utils;
2
3import com.google.common.cache.Cache;
4import com.google.common.cache.CacheBuilder;
5import org.springframework.stereotype.Component;
6
7import java.util.concurrent.TimeUnit;
8
9@Component
10public class BaseCache {
11
12
13
14 private Cache<String,Object> tenMinuteCache = CacheBuilder.newBuilder()
15
16 //设置缓存初始大小,应该合理设置,后续会扩容
17 .initialCapacity(10)
18 //最大值
19 .maximumSize(100)
20 //并发数设置
21 .concurrencyLevel(5)
22
23 //缓存过期时间,写入后10分钟过期
24 .expireAfterWrite(600,TimeUnit.SECONDS)
25
26 //统计缓存命中率
27 .recordStats()
28
29 .build();
30
31
32 public Cache<String, Object> getTenMinuteCache() {
33 return tenMinuteCache;
34 }
35
36 public void setTenMinuteCache(Cache<String, Object> tenMinuteCache) {
37 this.tenMinuteCache = tenMinuteCache;
38 }
39}
40
轮播图接口引入缓存
缓存 key 管理类
1package net.xdclass.online_xdclass.config;
2
3
4/**
5 * 缓存key管理类
6 */
7public class CacheKeyManager {
8
9 /**
10 * 首页轮播图缓存key
11 */
12 public static final String INDEX_BANNER_KEY = "index:banner";
13
14
15
16}
17
在 service 层引入 Guava cache
1package net.xdclass.online_xdclass.service.impl;
2
3import net.xdclass.online_xdclass.config.CacheKeyManager;
4import net.xdclass.online_xdclass.model.entity.Video;
5import net.xdclass.online_xdclass.model.entity.VideoBanner;
6import net.xdclass.online_xdclass.mapper.VideoMapper;
7import net.xdclass.online_xdclass.service.VideoService;
8import net.xdclass.online_xdclass.utils.BaseCache;
9import org.springframework.beans.factory.annotation.Autowired;
10import org.springframework.stereotype.Service;
11
12import java.util.List;
13
14
15@Service
16public class VideoServiceImpl implements VideoService {
17
18 @Autowired
19 private VideoMapper videoMapper;
20
21
22 @Autowired
23 private BaseCache baseCache;
24
25
26 @Override
27 public List<Video> listVideo() {
28
29 return videoMapper.listVideo();
30 }
31
32
33
34 @Override
35 public List<VideoBanner> listBanner() {
36
37 try{
38 //从缓存找不到就从数据库中找(回调)
39 Object cacheObj = baseCache.getTenMinuteCache().get(CacheKeyManager.INDEX_BANNER_KEY, ()->{
40
41 List<VideoBanner> bannerList = videoMapper.listVideoBanner();
42
43 System.out.println("从数据库里面找轮播图列表");
44
45 return bannerList;
46
47 });
48
49 if(cacheObj instanceof List){
50 List<VideoBanner> bannerList = (List<VideoBanner>)cacheObj;
51 return bannerList;
52 }
53
54 }catch (Exception e){
55 e.printStackTrace();
56 }
57 return null;
58 }
59
60
61
62
63 @Override
64 public Video findDetailById(int videoId) {
65
66 // 需要使用mybaits关联复杂查询
67 Video video = videoMapper.findDetailById(videoId);
68
69 return video;
70 }
71}
72
测试
1http://localhost:8081/api/v1/pub/video/list_banner
2
3只有第一次请求 打印 从数据库里面找轮播图列表
4之后10分钟内请求直接从缓存中取出
视频列表引入缓存
缓存 key 管理类
1package net.xdclass.online_xdclass.config;
2
3
4/**
5 * 缓存key管理类
6 */
7public class CacheKeyManager {
8
9 /**
10 * 首页轮播图缓存key
11 */
12 public static final String INDEX_BANNER_KEY = "index:banner:list";
13
14
15 /**
16 * 首页视频列表缓存key
17 */
18 public static final String INDEX_VIDEL_LIST = "index:video:list";
19}
20
在 service 层中引入缓存
1package net.xdclass.online_xdclass.service.impl;
2
3import net.xdclass.online_xdclass.config.CacheKeyManager;
4import net.xdclass.online_xdclass.model.entity.Video;
5import net.xdclass.online_xdclass.model.entity.VideoBanner;
6import net.xdclass.online_xdclass.mapper.VideoMapper;
7import net.xdclass.online_xdclass.service.VideoService;
8import net.xdclass.online_xdclass.utils.BaseCache;
9import org.springframework.beans.factory.annotation.Autowired;
10import org.springframework.stereotype.Service;
11
12import java.util.List;
13
14
15@Service
16public class VideoServiceImpl implements VideoService {
17
18 @Autowired
19 private VideoMapper videoMapper;
20
21
22 @Autowired
23 private BaseCache baseCache;
24
25
26 @Override
27 public List<Video> listVideo() {
28
29
30 try{
31
32 Object cacheObj = baseCache.getTenMinuteCache().get(CacheKeyManager.INDEX_VIDEL_LIST,()->{
33
34 List<Video> videoList = videoMapper.listVideo();
35 System.out.println("从数据库中查询");
36
37 return videoList;
38
39 });
40
41 if(cacheObj instanceof List){
42 List<Video> videoList = (List<Video>)cacheObj;
43 return videoList;
44 }
45
46 }catch (Exception e){
47 e.printStackTrace();
48 }
49
50 //可以返回兜底数据,业务系统降级-》SpringCloud专题课程
51 return null;
52 }
53
54
55
56 @Override
57 public List<VideoBanner> listBanner() {
58
59 try{
60
61 Object cacheObj = baseCache.getTenMinuteCache().get(CacheKeyManager.INDEX_BANNER_KEY, ()->{
62
63 List<VideoBanner> bannerList = videoMapper.listVideoBanner();
64
65 System.out.println("从数据库里面找轮播图列表");
66
67 return bannerList;
68
69 });
70
71 if(cacheObj instanceof List){
72 List<VideoBanner> bannerList = (List<VideoBanner>)cacheObj;
73 return bannerList;
74 }
75
76 }catch (Exception e){
77 e.printStackTrace();
78 }
79 return null;
80 }
81
82
83
84
85 @Override
86 public Video findDetailById(int videoId) {
87
88 // 需要使用mybaits关联复杂查询
89 Video video = videoMapper.findDetailById(videoId);
90
91 return video;
92 }
93}
94
测试
1http://localhost:8081/api/v1/pub/video/list
2
3只有第一次请求 打印 从数据库里面找轮播图列表
4之后10分钟内请求直接从缓存中取出
视频详情引入缓存
缓存 key 管理类
1package net.xdclass.online_xdclass.config;
2
3
4/**
5 * 缓存key管理类
6 */
7public class CacheKeyManager {
8
9 /**
10 * 首页轮播图缓存key
11 */
12 public static final String INDEX_BANNER_KEY = "index:banner:list";
13
14
15 /**
16 * 首页视频列表缓存key
17 */
18 public static final String INDEX_VIDEL_LIST = "index:video:list";
19
20
21 /**
22 * 视频详情缓存key, %s是视频id
23 */
24 public static final String VIDEO_DETAIL = "video:detail:%s";
25
26
27}
28
在 service 层引入缓存
1package net.xdclass.online_xdclass.service.impl;
2
3import net.xdclass.online_xdclass.config.CacheKeyManager;
4import net.xdclass.online_xdclass.model.entity.Video;
5import net.xdclass.online_xdclass.model.entity.VideoBanner;
6import net.xdclass.online_xdclass.mapper.VideoMapper;
7import net.xdclass.online_xdclass.service.VideoService;
8import net.xdclass.online_xdclass.utils.BaseCache;
9import org.springframework.beans.factory.annotation.Autowired;
10import org.springframework.stereotype.Service;
11
12import java.util.List;
13
14
15@Service
16public class VideoServiceImpl implements VideoService {
17
18 @Autowired
19 private VideoMapper videoMapper;
20
21
22 @Autowired
23 private BaseCache baseCache;
24
25
26 @Override
27 public List<Video> listVideo() {
28
29
30 try{
31
32 Object cacheObj = baseCache.getTenMinuteCache().get(CacheKeyManager.INDEX_VIDEL_LIST,()->{
33
34 List<Video> videoList = videoMapper.listVideo();
35
36 return videoList;
37
38 });
39
40 if(cacheObj instanceof List){
41 List<Video> videoList = (List<Video>)cacheObj;
42 return videoList;
43 }
44
45 }catch (Exception e){
46 e.printStackTrace();
47 }
48
49 //可以返回兜底数据,业务系统降级-》SpringCloud专题课程
50 return null;
51 }
52
53
54
55 @Override
56 public List<VideoBanner> listBanner() {
57
58 try{
59
60 Object cacheObj = baseCache.getTenMinuteCache().get(CacheKeyManager.INDEX_BANNER_KEY, ()->{
61
62 List<VideoBanner> bannerList = videoMapper.listVideoBanner();
63
64 System.out.println("从数据库里面找轮播图列表");
65
66 return bannerList;
67
68 });
69
70 if(cacheObj instanceof List){
71 List<VideoBanner> bannerList = (List<VideoBanner>)cacheObj;
72 return bannerList;
73 }
74
75 }catch (Exception e){
76 e.printStackTrace();
77 }
78 return null;
79 }
80
81
82
83
84 @Override
85 public Video findDetailById(int videoId) {
86
87 //单独构建一个缓存key,每个视频的key是不一样的
88 String videoCacheKey = String.format(CacheKeyManager.VIDEO_DETAIL,videoId);
89
90 try{
91
92 Object cacheObject = baseCache.getOneHourCache().get( videoCacheKey, ()->{
93
94 // 需要使用mybaits关联复杂查询
95 Video video = videoMapper.findDetailById(videoId);
96
97 return video;
98
99 });
100
101 if(cacheObject instanceof Video){
102
103 Video video = (Video)cacheObject;
104 return video;
105 }
106
107 }catch (Exception e){
108 e.printStackTrace();
109 }
110
111 return null;
112 }
113}
114
测试(三表关联查询特别耗费性能,明显从缓存中读取性能开销要小的多)
1http://localhost:8081/api/v1/pub/video/find_detail_by_id?video_id=42
2
3
4{
5 "code": 0,
6 "data": {
7 "id": 42,
8 "title": "全新elementUI项目实战教程Vue整合Echarts后台权限",
9 "summary": "https://xd-video-pc-img.oss-cn-beijing.aliyuncs.com/xdclass_pro/video/2019_frontend/element/elementui_detail.png",
10 "price": 5980,
11 "point": 8.7,
12 "cover_img": "https://xd-video-pc-img.oss-cn-beijing.aliyuncs.com/xdclass_pro/video/2019_frontend/element/elementui.png",
13 "create_time": "2019-10-11 06:14:00",
14 "chapter_list": [
15 {
16 "id": 450,
17 "title": "课程介绍",
18 "ordered": 1,
19 "video_id": null,
20 "create_time": "2019-09-06 06:39:59",
21 "episode_list": [
22 {
23 "id": 11690,
24 "title": "小滴后台管理系统课程介绍",
25 "num": 1,
26 "ordered": 1,
27 "free": 0,
28 "play_url": "xdclass.net/aaa.mp4",
29 "chapter_id": null,
30 "video_id": null,
31 "create_time": null
32 }
33 ]
34 },
35 {
36 "id": 451,
37 "title": "Vue全家桶各部分核⼼知识详解",
38 "ordered": 2,
39 "video_id": null,
40 "create_time": "2019-09-06 06:39:59",
41 "episode_list": [
42 {
43 "id": 11691,
44 "title": "构建vue项目的利器—脚手架vue-cli3详解",
45 "num": 2,
46 "ordered": 1,
47 "free": 0,
48 "play_url": "xdclass.net/aaa.mp4",
49 "chapter_id": null,
50 "video_id": null,
51 "create_time": null
52 },
53 {
54 "id": 11692,
55 "title": "vue中组件间传值常用的几种方式(上)",
56 "num": 3,
57 "ordered": 2,
58 "free": 0,
59 "play_url": "xdclass.net/aaa.mp4",
60 "chapter_id": null,
61 "video_id": null,
62 "create_time": null
63 },
64 {
65 "id": 11693,
66 "title": "vue中组件间传值常用的几种方式(下)",
67 "num": 4,
68 "ordered": 3,
69 "free": 1,
70 "play_url": "xdclass.net/aaa.mp4",
71 "chapter_id": null,
72 "video_id": null,
73 "create_time": null
74 },
75 {
76 "id": 11694,
77 "title": "玩转单页面应用的控制中心—vue-router",
78 "num": 5,
79 "ordered": 4,
80 "free": 1,
81 "play_url": "xdclass.net/aaa.mp4",
82 "chapter_id": null,
83 "video_id": null,
84 "create_time": null
85 },
86 {
87 "id": 11695,
88 "title": "状态管理中心—vuex的基础用法",
89 "num": 6,
90 "ordered": 5,
91 "free": 1,
92 "play_url": "xdclass.net/aaa.mp4",
93 "chapter_id": null,
94 "video_id": null,
95 "create_time": null
96 },
97 {
98 "id": 11696,
99 "title": "状态管理中心—vuex的高级用法",
100 "num": 7,
101 "ordered": 6,
102 "free": 1,
103 "play_url": "xdclass.net/aaa.mp4",
104 "chapter_id": null,
105 "video_id": null,
106 "create_time": null
107 }
108 ]
109 },
110 {
111 "id": 452,
112 "title": "Element常用组件详解",
113 "ordered": 3,
114 "video_id": null,
115 "create_time": "2019-09-06 06:39:59",
116 "episode_list": [
117 {
118 "id": 11697,
119 "title": "Element常用组件布局组件详解",
120 "num": 8,
121 "ordered": 1,
122 "free": 1,
123 "play_url": "xdclass.net/aaa.mp4",
124 "chapter_id": null,
125 "video_id": null,
126 "create_time": null
127 },
128 {
129 "id": 11698,
130 "title": "Element常用组件之弹出类型组件详解",
131 "num": 9,
132 "ordered": 2,
133 "free": 1,
134 "play_url": "xdclass.net/aaa.mp4",
135 "chapter_id": null,
136 "video_id": null,
137 "create_time": null
138 },
139 {
140 "id": 11699,
141 "title": "Element常用组件—表格组件详解",
142 "num": 10,
143 "ordered": 3,
144 "free": 1,
145 "play_url": "xdclass.net/aaa.mp4",
146 "chapter_id": null,
147 "video_id": null,
148 "create_time": null
149 },
150 {
151 "id": 11700,
152 "title": "Element常用组件—表单组件详解",
153 "num": 11,
154 "ordered": 4,
155 "free": 1,
156 "play_url": "xdclass.net/aaa.mp4",
157 "chapter_id": null,
158 "video_id": null,
159 "create_time": null
160 }
161 ]
162 },
163 {
164 "id": 453,
165 "title": "实战项⽬之环境准备及配置改装",
166 "ordered": 4,
167 "video_id": null,
168 "create_time": "2019-09-06 06:39:59",
169 "episode_list": [
170 {
171 "id": 11701,
172 "title": "项目搭建及技术选型",
173 "num": 12,
174 "ordered": 1,
175 "free": 1,
176 "play_url": "xdclass.net/aaa.mp4",
177 "chapter_id": null,
178 "video_id": null,
179 "create_time": null
180 },
181 {
182 "id": 11702,
183 "title": "配置项目的基本环境及项目目录结构总体介绍",
184 "num": 13,
185 "ordered": 2,
186 "free": 1,
187 "play_url": "xdclass.net/aaa.mp4",
188 "chapter_id": null,
189 "video_id": null,
190 "create_time": null
191 }
192 ]
193 },
194 {
195 "id": 454,
196 "title": "⼩滴课堂后台视频管理系统之公用部分开发",
197 "ordered": 5,
198 "video_id": null,
199 "create_time": "2019-09-06 06:39:59",
200 "episode_list": [
201 {
202 "id": 11703,
203 "title": "需求分析及模块划分",
204 "num": 14,
205 "ordered": 1,
206 "free": 1,
207 "play_url": "xdclass.net/aaa.mp4",
208 "chapter_id": null,
209 "video_id": null,
210 "create_time": null
211 },
212 {
213 "id": 11704,
214 "title": "路由设计及左侧公用导航菜单开发",
215 "num": 15,
216 "ordered": 2,
217 "free": 1,
218 "play_url": "xdclass.net/aaa.mp4",
219 "chapter_id": null,
220 "video_id": null,
221 "create_time": null
222 },
223 {
224 "id": 11705,
225 "title": "顶部导航菜单及与左侧导航联动的面包屑实现(上)",
226 "num": 16,
227 "ordered": 3,
228 "free": 1,
229 "play_url": "xdclass.net/aaa.mp4",
230 "chapter_id": null,
231 "video_id": null,
232 "create_time": null
233 },
234 {
235 "id": 11706,
236 "title": "顶部导航菜单及与左侧导航联动的面包屑实现(下)",
237 "num": 17,
238 "ordered": 4,
239 "free": 1,
240 "play_url": "xdclass.net/aaa.mp4",
241 "chapter_id": null,
242 "video_id": null,
243 "create_time": null
244 },
245 {
246 "id": 11707,
247 "title": "使用vuex实现切换tab页功能",
248 "num": 18,
249 "ordered": 5,
250 "free": 1,
251 "play_url": "xdclass.net/aaa.mp4",
252 "chapter_id": null,
253 "video_id": null,
254 "create_time": null
255 },
256 {
257 "id": 11708,
258 "title": "构建页面组件,连通公共组件",
259 "num": 19,
260 "ordered": 6,
261 "free": 1,
262 "play_url": "xdclass.net/aaa.mp4",
263 "chapter_id": null,
264 "video_id": null,
265 "create_time": null
266 },
267 {
268 "id": 11709,
269 "title": "页面布局整体样式优化",
270 "num": 20,
271 "ordered": 7,
272 "free": 1,
273 "play_url": "xdclass.net/aaa.mp4",
274 "chapter_id": null,
275 "video_id": null,
276 "create_time": null
277 }
278 ]
279 },
280 {
281 "id": 455,
282 "title": "⼩D课堂后台视频管理系统之⾸页开发",
283 "ordered": 6,
284 "video_id": null,
285 "create_time": "2019-09-06 06:39:59",
286 "episode_list": [
287 {
288 "id": 11710,
289 "title": "介绍mock.js及axios全局配置",
290 "num": 21,
291 "ordered": 1,
292 "free": 1,
293 "play_url": "xdclass.net/aaa.mp4",
294 "chapter_id": null,
295 "video_id": null,
296 "create_time": null
297 },
298 {
299 "id": 11711,
300 "title": "使用Mock随机返回主页数据",
301 "num": 22,
302 "ordered": 2,
303 "free": 1,
304 "play_url": "xdclass.net/aaa.mp4",
305 "chapter_id": null,
306 "video_id": null,
307 "create_time": null
308 },
309 {
310 "id": 11712,
311 "title": "使用element布局组件实现首页布局",
312 "num": 23,
313 "ordered": 3,
314 "free": 1,
315 "play_url": "xdclass.net/aaa.mp4",
316 "chapter_id": null,
317 "video_id": null,
318 "create_time": null
319 },
320 {
321 "id": 11713,
322 "title": "完成首页除图表外的内容",
323 "num": 24,
324 "ordered": 4,
325 "free": 1,
326 "play_url": "xdclass.net/aaa.mp4",
327 "chapter_id": null,
328 "video_id": null,
329 "create_time": null
330 },
331 {
332 "id": 11714,
333 "title": "完成首页table部分及ECharts介绍",
334 "num": 25,
335 "ordered": 5,
336 "free": 1,
337 "play_url": "xdclass.net/aaa.mp4",
338 "chapter_id": null,
339 "video_id": null,
340 "create_time": null
341 },
342 {
343 "id": 11715,
344 "title": "谈谈封装一个EChart组件的一些想法",
345 "num": 26,
346 "ordered": 6,
347 "free": 1,
348 "play_url": "xdclass.net/aaa.mp4",
349 "chapter_id": null,
350 "video_id": null,
351 "create_time": null
352 },
353 {
354 "id": 11716,
355 "title": "上手封装一个EChart组件并处理数据展示图表",
356 "num": 27,
357 "ordered": 7,
358 "free": 1,
359 "play_url": "xdclass.net/aaa.mp4",
360 "chapter_id": null,
361 "video_id": null,
362 "create_time": null
363 },
364 {
365 "id": 11717,
366 "title": "修改EChart组件样式及自适应图表(上)",
367 "num": 28,
368 "ordered": 8,
369 "free": 1,
370 "play_url": "xdclass.net/aaa.mp4",
371 "chapter_id": null,
372 "video_id": null,
373 "create_time": null
374 },
375 {
376 "id": 11718,
377 "title": "修改EChart组件样式自适应图表(下)",
378 "num": 29,
379 "ordered": 9,
380 "free": 1,
381 "play_url": "xdclass.net/aaa.mp4",
382 "chapter_id": null,
383 "video_id": null,
384 "create_time": null
385 },
386 {
387 "id": 11719,
388 "title": "Echart组件封装总结",
389 "num": 30,
390 "ordered": 10,
391 "free": 1,
392 "play_url": "xdclass.net/aaa.mp4",
393 "chapter_id": null,
394 "video_id": null,
395 "create_time": null
396 }
397 ]
398 },
399 {
400 "id": 456,
401 "title": "用户管理页及详解权限管理",
402 "ordered": 7,
403 "video_id": null,
404 "create_time": "2019-09-06 06:39:59",
405 "episode_list": [
406 {
407 "id": 11720,
408 "title": "用户管理页介绍及页面实现思路讲解",
409 "num": 31,
410 "ordered": 1,
411 "free": 1,
412 "play_url": "xdclass.net/aaa.mp4",
413 "chapter_id": null,
414 "video_id": null,
415 "create_time": null
416 },
417 {
418 "id": 11721,
419 "title": "更完善的表单组件封装及思路讲解",
420 "num": 32,
421 "ordered": 2,
422 "free": 1,
423 "play_url": "xdclass.net/aaa.mp4",
424 "chapter_id": null,
425 "video_id": null,
426 "create_time": null
427 },
428 {
429 "id": 11722,
430 "title": "通用表格组件封装及思路讲解",
431 "num": 33,
432 "ordered": 3,
433 "free": 1,
434 "play_url": "xdclass.net/aaa.mp4",
435 "chapter_id": null,
436 "video_id": null,
437 "create_time": null
438 },
439 {
440 "id": 11723,
441 "title": "完成表格组件的封装",
442 "num": 34,
443 "ordered": 4,
444 "free": 1,
445 "play_url": "xdclass.net/aaa.mp4",
446 "chapter_id": null,
447 "video_id": null,
448 "create_time": null
449 },
450 {
451 "id": 11724,
452 "title": "用户管理页页面功能实现(上)",
453 "num": 35,
454 "ordered": 5,
455 "free": 1,
456 "play_url": "xdclass.net/aaa.mp4",
457 "chapter_id": null,
458 "video_id": null,
459 "create_time": null
460 },
461 {
462 "id": 11725,
463 "title": "用户管理页页面功能实现(下)",
464 "num": 36,
465 "ordered": 6,
466 "free": 1,
467 "play_url": "xdclass.net/aaa.mp4",
468 "chapter_id": null,
469 "video_id": null,
470 "create_time": null
471 },
472 {
473 "id": 11726,
474 "title": "企业开发之权限管理思路讲解",
475 "num": 37,
476 "ordered": 7,
477 "free": 1,
478 "play_url": "xdclass.net/aaa.mp4",
479 "chapter_id": null,
480 "video_id": null,
481 "create_time": null
482 },
483 {
484 "id": 11727,
485 "title": "权限管理之动态返回菜单的实现",
486 "num": 38,
487 "ordered": 8,
488 "free": 1,
489 "play_url": "xdclass.net/aaa.mp4",
490 "chapter_id": null,
491 "video_id": null,
492 "create_time": null
493 },
494 {
495 "id": 11728,
496 "title": "权限管理之路由守卫判断用户登录状态",
497 "num": 39,
498 "ordered": 9,
499 "free": 1,
500 "play_url": "xdclass.net/aaa.mp4",
501 "chapter_id": null,
502 "video_id": null,
503 "create_time": null
504 }
505 ]
506 },
507 {
508 "id": 457,
509 "title": "项⽬总结",
510 "ordered": 8,
511 "video_id": null,
512 "create_time": "2019-09-06 06:39:59",
513 "episode_list": [
514 {
515 "id": 11729,
516 "title": "小滴后台管理系统项目总结",
517 "num": 40,
518 "ordered": 1,
519 "free": 1,
520 "play_url": "xdclass.net/aaa.mp4",
521 "chapter_id": null,
522 "video_id": null,
523 "create_time": null
524 }
525 ]
526 }
527 ]
528 },
529 "msg": null
530}
531
532
Jemeter 压测
聚合报告参数详解
1lable: sampler的名称
2Samples: 一共发出去多少请求,例如10个用户,循环10次,则是 100
3Average: 平均响应时间
4Median: 中位数,也就是 50% 用户的响应时间
5
6
790% Line : 90% 用户的响应不会超过该时间 (90% of the samples took no more than this time. The remaining samples at least as long as this)
895% Line : 95% 用户的响应不会超过该时间
999% Line : 99% 用户的响应不会超过该时间
10min : 最小响应时间
11max : 最大响应时间
12
13
14
15Error%:错误的请求的数量/请求的总数
16Throughput: 吞吐量——默认情况下表示每秒完成的请求数(Request per Second) 可类比为qps、tps
17KB/Sec: 每秒接收数据量
压测参数: 300 5 2000
QPS 压测 qps 结果为: Throughput: 7563/sec
http 127.0.0.1 8081 /api/v1/pub/video/list_banner
取消缓存 再进行测试 Throughput: 4060/sec