前言

同样我们以上一篇文章为例子,搭建好环境之后,我欧美可以模拟高并发场景下,我们的缓存效率怎么样,到底能不能解决我们实际项目中的缓存问题。也就是如何解决缓存穿透?

Spring Boot集成Redis缓存高并发条件下处理

方式一、针数据量不是很大的情况下

之间加入同步锁synchronized、也能解决问题

@Override
public synchronized List<User> findAll() {业务省略.................
}

开始模拟Redis缓存高并发场景

UserController.java

 /**** 查询用户信息List集合 模拟用户高并发请求* @param model* @return*/@GetMapping(value = "index")public String index(Model model){//线程、该线程调用底层所有查询用户信息的方法Runnable runnable = new Runnable() {@Overridepublic void run() {userService.findAll();}};//多线程测试一下缓存穿透,模拟1万人同时访问ExecutorService executorService = Executors.newFixedThreadPool(25);for(int i=0 ; i<10000 ; i++){executorService.submit(runnable);}List<User> userList = userService.findAll();model.addAttribute("userList",userList);return "admin/index";}

我们先不加人同步锁synchronized看看缓存效果

UserServiceImpl.java

@Service
public class UserServiceImpl implements UserService {@AutowiredUserDao userDao;//注入spring boot 自动配置好的RedisTemplate@Autowiredprivate RedisTemplate<Object,Object> redisTemplate;@Overridepublic List<User> findAll() {//1、设置key字符串的序列化器RedisSerializer redisSerializer = new StringRedisSerializer();redisTemplate.setKeySerializer(redisSerializer);//2、查询Redis缓存List<User> userList = (List<User>) redisTemplate.opsForValue().get("allUsers");if(null == userList){System.out.println("查询数据库.......");//缓存为空,查询一遍数据库userList = userDao.findAll();//把查询出来的数据放入Redis中redisTemplate.opsForValue().set("allUsers",userList);}else{System.out.println("查询Redis中的缓存.......");}return userList;}
}

控制台打印

查询数据库.......
查询数据库.......
查询数据库.......
查询数据库.......
查询数据库.......
2020-05-11 19:32:48.114  INFO 12988 --- [ool-1-thread-25] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} inited
查询Redis中的缓存.......
查询Redis中的缓存.......
查询Redis中的缓存.......
查询Redis中的缓存.......
查询Redis中的缓存.......
从中可看出一部分人请求了数据库、一部分请求了缓存、此时便出现了缓存穿透

方案一:这时加人同步锁synchronized再看看缓存效果

 //模拟高并发场景、加入synchronized同步锁@Overridepublic synchronized List<User> findAll() {省略了,这部分代码和上面一样....}

加入synchronized同步锁、控制台打印

查询数据库.......
2020-05-11 19:37:44.877  INFO 7164 --- [pool-1-thread-1] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} inited
查询Redis中的缓存.......
查询Redis中的缓存.......
查询Redis中的缓存.......
查询Redis中的缓存.......
查询Redis中的缓存.......
Java 中的 synchronized 关键字可以在多线程环境下用来作为线程安全的同步锁,可以看出针数据量不是很大的情况下,加入synchronized同步锁能解决缓存穿透问题。那么问题来了,大数据量又怎么解决呢?

方式二:加入双重检测锁解决缓存穿透

UserServiceImpl.java,修改一下代码

//高并发条件下:出现缓存穿透、双重检测锁进行解决@Overridepublic synchronized List<User> findAll() {//1、设置key字符串的序列化器RedisSerializer redisSerializer = new StringRedisSerializer();redisTemplate.setKeySerializer(redisSerializer);//2、查询Redis缓存List<User> userList = (List<User>) redisTemplate.opsForValue().get("allUsers");if(null == userList){//加入锁进行锁定synchronized(this) {//加入锁,不同的人进来,先再从redis中获取以下,也就是说第一个进来了,后面的人再进来就可以直接读缓存中的数据了userList = (List<User>) redisTemplate.opsForValue().get("allUsers");//再进行判断if (null == userList) {System.out.println("查询的数据库......");//缓存为空,查询一遍数据库userList = userDao.findAll();//把查询出来的数据放入Redis中redisTemplate.opsForValue().set("allUsers", userList);} else {System.out.println("进来了、还是查询Redis中的缓存.......");}}}else{System.out.println("查询Redis中的缓存.......");}return userList;}

控制台输出

查询的数据库......
2020-05-11 19:48:01.976  INFO 9396 --- [pool-1-thread-2] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} inited
查询Redis中的缓存.......
查询Redis中的缓存.......
查询Redis中的缓存.......

我们将并发数量再改大一点 比如10万人同时访问,也是没问题的

Spring Boot集成Redis缓存之模拟高并发场景处理相关推荐

  1. 猿创征文 | 微服务 Spring Boot 整合Redis 实战开发解决高并发数据缓存

    文章目录 一.什么是 缓存? ⛅为什么用缓存? ⚡如何使用缓存 二.实现一个商家缓存 ⌛环境搭建 ♨️核心源码 ✅测试接口 三.采用 微服务 Spring Boot 注解开启缓存 ✂️@CacheEn ...

  2. Spring Boot 集成 Redis 缓存

    Spring Boot 集成 Redis 缓存 在此章,我们将 SpringBoot 集成 Redis 缓存,Redis是一个开源的,基于内存的数据结构存储,可以用作数据库.缓存和消息代理,在本章仅讲 ...

  3. Spring Boot集成Redis缓存之RedisTemplate的方式

    前言 Spring Boot 集成Redis,将自动配置 RedisTemplate,在需要使用的类中注入RedisTemplate的bean即可使用 @Autowired private Redis ...

  4. Spring Boot集成Redis缓存之注解方式

    首先还是加入依赖Jar pom.xml中加入依赖 <!-- 加载spring boot redis 包 --><dependency><groupId>org.sp ...

  5. Linux 安装Redis-6.2.5,配置及使用(RDB与AOF持久化、sentinel机制、主从复制、Spring Boot 集成 Redis)

    CentOS 7 安装Redis-6.2.5版本 Redis采用的是基于内存的单进程 单线程模型 的KV数据库,由C语言编写.官方提供的数据是可以达到100000+的qps 应用场景: 令牌(Toke ...

  6. Spring Boot 结合 Redis 缓存

    Redis官网: 中:http://www.redis.cn/ 外:https://redis.io/ redis下载和安装 Redis官方并没有提供Redis的Windows版本,这里使用微软提供的 ...

  7. Spring boot - 整合 Redis缓存(上)

    一.配置Pom文件 在使用spring boot 2.0整合redis时遇到了好多问题,网上很多例子都是1.x版本的.故2.0没有折腾好所以将2.0降到了1.5.降级后由于thymeleaf版本也会从 ...

  8. 模拟高并发场景工具:siege

    1.模拟高并发场景 1.1 安装工具:siege wget http://download.joedog.org/siege/siege-latest.tar.gz tar -zxvf siege-l ...

  9. Spring Boot集成Redis实现缓存

    前言 在此章,我们将 SpringBoot 集成 Redis缓存,Redis是一个开源的,基于内存的数据结构存储,可以用作数据库.缓存和消息代理,在本章仅讲解缓存集成.一键获取源码地址 准备工作 当前 ...

最新文章

  1. 逃计算机课检讨书600字,检讨书600字3篇
  2. Myeclipse的破解步骤
  3. NB-IOT环境监测项目需求分析
  4. SAP UI5 ResponsiveGridLayout
  5. android 刷rom,刷ROM是什么?刷ROM是什么意思?
  6. 网络管理软件免费linux,最新Xmanager Power Suite6网络管理工具免费官方下载6.0.199 - 系统之家...
  7. Java 异常类层次结构
  8. python cls参数_python cls self 讲解
  9. Linux-Anaconda-pycharm 安装 配置
  10. Linux设置时间和硬件时间
  11. 3GPP TS 23502-h20 中英文对照 | 4.15.6.2 NEF service operations information flow
  12. 曙光超级计算机用的芯片是国产吗,真正中国芯片龙头是中科曙光
  13. 计算机开机网络连接启动慢,四个小技巧轻松解决电脑开机后网络连接慢问题
  14. qq实验报告c语言,C语言实现QQ密码大盗(没试验过,下回验证一下)
  15. 操练Draco的代码
  16. 【数据分析 —— 认识数据】
  17. 如何将白鹭引擎开发的游戏通过Egret Native发布到 GooglePlay平台
  18. 国际奥林匹克数学比赛给用计算机吗,国际奥林匹克数学竞赛怎样参赛?有何标准?...
  19. PX4 Autopilot源码分析 - 代码下载
  20. RJ45与RJ48的区别

热门文章

  1. 信息学奥赛一本通 1053:最大数输出 | OpenJudge NOI 1.4 15
  2. 训练日志 2019.4.13
  3. 训练日志 2018.10.18
  4. 信息学奥赛C++语言:顺序输出
  5. 信息学奥赛一本通C++语言——1046:判断一个数能否同时被3和5整除
  6. Java主要处理哪些类型的异常_Java技术高效处理异常有哪些呢?
  7. linux内核启动过程5:启动用户空间
  8. 心态很容易受别人影响_女人生宝宝也看年龄?这3个影响生育能力的因素,你得了解清楚...
  9. VMware Tools显示灰色的办法
  10. 【PyTorch】PixelShuffle