springboot+redis 并发2000时QPS低

ahbhm 2020-08-03 04:55:07
1.做的一个项目,涉及到性能的压测,架构为springboot+redis,为了提升查询性能,由以前的查库改为查缓存,

利用redis的lettuce,来操作redis,lettuce配置如图:

spring:

# redis

redis:

isopen: true

database:0

host: 127.0.0.1

port:6379

lettuce:

pool:

max-active:-1

max-wait: 100

max-idle:8

min-idle:0

timeout: 5000

redis中提前放置一条数据,获取缓存,controller的代码如下:

@CrossOrigin

@GetMapping(value ="/handle", produces ="application/json;charset=UTF-8")

@ResponseBody

public StringqueryHandle(@RequestParam(value ="identity") String handleIdentity)throws JSONException {

if(isCache &&redisUtil.exists(handleIdentity)){

return redisUtil.get(handleIdentity).toString();

}

redisUtil.get的方法如下:

public Object get(String key){

return key ==null ?null :redisTemplate.opsForValue().get(key);

}

用jmeter进行性能测试,在并发2000,循环10次的情况下,结果如图,性能出乎意料的差,有没有大神能指教一下,什么原因导致的性能这么差,redis的单机不是号称QPS在几万吗?




...全文
3679 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
maradona1984 2020-08-04
  • 打赏
  • 举报
回复
单台机器能做到2000并发么...你这tomcat线程池大小有没有调整呢
hashcon 2020-08-04
  • 打赏
  • 举报
回复 3
你在服务器上面跑的jmeter错误率是100%诶,你先看看是什么错吧。 还有,性能压测方法最好注意下。如果你要压测,首先,要先测试脚本空跑TPS多少,然后,脚本直接操作Redis TPS多少,最后,才是调用你的Spring Boot接口跑。这样你会发现,可能是你的CPU或者内存资源不足,导致TPS上不去。 并且,测试Java程序,尤其是Spring 程序,要预热,因为JVM分层优化,C1,C2优化器都需要代码被运行多次才会优化,否则你的代码都要经过解释器才会被机器执行,并不是机器码直接执行,速度差很多,并且Spring启动时加载一大堆东西导致codecache需要清理,清理的时候会STW,并且Spring Boot 的Controller第一次运行是Dispatcher懒加载的,需要动态加载,所以一定要预热。你在服务器上面跑的Jmeter,一共就2000次,C1优化默认代码要执行5000次以上的。
xyjsqd 2020-08-04
  • 打赏
  • 举报
回复
不好意思 我是来混一下的
小心仔 2020-08-04
  • 打赏
  • 举报
回复
大神
ITjavaman 2020-08-04
  • 打赏
  • 举报
回复
硬件资源还剩多少,CPU跑满了没有 tomcat上跑?tomcat调优了没? 句柄数多少?另外压测机cpu跟带宽跑满了没有
ahbhm 2020-08-03
  • 打赏
  • 举报
回复
是的,但是把jemter放在服务器上测试后,结果也差不多,相差不大,
伫望-向北 2020-08-03
  • 打赏
  • 举报
回复
你这个是在自己电脑开jmeter测自己电脑跑的项目吧
【资源说明】 1、基于SpringBoot的高并发选课系统源码+项目说明(毕设).zip 2、该资源包括项目的全部源码,下载可以直接使用! 3、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,作为参考资料学习借鉴。 4、本资源作为“参考资料”如果需要实现其他功能,需要能看懂代码,并且热爱钻研,自行调试。 ## 项目简介 本项目主要解决在高校选课场景下,保证选课系统在大量读写压力下不宕机,以及选课尽可能提高选课QPS,给学生一个良好的选课体验,完成上述功能同保证选课安全 ## 技术选型 前端:Bootstrap、JQuery、Thymeleaf 后端:SpringBoot、Shiro、JPA、Caffeine 中间件:Redis、RabbitMQ、Druid 数据库:MySQL ## 优化思路 ### 页面查看 解决思路:从Redis缓存中查看数据,减少数据库访问 从数据可见性角度来讲,分为对所有人可见的公有信息,和只有自己可见的私有信息 ### 登陆 1. 学生可能多次登陆系统,第一次登陆将学生信息加载进Redis,减少后续登陆对数据库的访问 2. 通过单例模式构建全局唯一类,根据sessionID保存学生学号,供后续使用 ### 选课 **_此功能为整个系统的重点优化之处,_** 主要分为两大步骤,选课安全验证和执行选课操作 #### **选课安全验证** 1. IP限流,每分钟可以访问三次,与学号绑定,通过Redis实现 ```java Integer sno = StudentIDUtils.getStudentIDFromMap(); Integer count = (Integer) redisService.get("ip-", String.valueOf(sno)); if (count == null) { //一分钟内可以访问三次 redisService.set("ip-", String.valueOf(sno), 1, 1, TimeUnit.MINUTES); }else if (count < 3){ redisService.incr("ip-"+sno, 1); }else { throw new GlobalException(CodeMsg.COUNT_OVER); } ``` 2. 判断是否存在该课程,从Redis中查看 3. 判断是否在规定选课限范围内,从Redis中查看 4. 若满足上述步骤,根据课程号生成其md5值,暴露秒杀地址 5. 执行选课操作验证秒杀地址是否正确 #### 执行选课操作 1. 通过本地标记判断是否有余量,若有,执行后续 2. 判断是否重选,通过查看Redis是否有对应缓存来实现 3. 判断上课间是否冲突,构造冲突判断算法,遍历Redis中已选课程进行验证 4. 库存预减,当库存为0,将该授课计划添加到本地缓存中,本地缓存通过Caffeine构建 ```java Long num = redisService.hdecr("forPlanCount", String.valueOf(pno), 1); // LOGGER.info("redis中读取pno={} 的授课计划余量为{}", pno, num); if(num < 0){ //没余量,写入本地缓存中 caffeineCache.put(pno, true); throw new GlobalException(CodeMsg.PlAN_OVER); } ``` 5. 选课请求压入MQ,异步执行,流量削峰,消费端消费选课信息,将结果写入数据库,结果写入数据库这一步采用事务机制,先插入结果,后减余量,减少事务期间锁持有间,优化数据库读写性能 6. 返回执行成功标识,但结果需要到选课查询页面确认 #### 预加载 ```java @Service public class ChooseServiceImpl implements ChooseService, InitializingBean { @Override public void afterPropertiesSet() throws Exception { //预加载相关操作 } } ``` 通过上述代码所示,Spring

67,514

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧