对于大并发量的系统,有几个可能须要优化的点,下面咱们要一步步测试来优化这个系统。redis
对于一个系统,几个经常使用的评价指标是:平均响应时间、吞吐率、qps等。个人测试主要测试3个接口sql
主页(访问根路径,没有数据库交互)
秒杀接口暴露(暴露秒杀接口,有后台数据交互)
执行秒杀操做(插入秒杀成功记录和减库存一个完整的事务操做)
对于这三个接口,咱们主要的测试目标和优化目标是平均响应时间,固然这是创建在数据正确返回的基础上的,失败率过高那这个平均响应时间是没有意义的。
这里的优化侧重于后端数据库和内存方面的优化。数据库
我是在Windows10下用jmeter来进行负载测试和压力测试,其余环境以下,涉及具体配置再提。windows
Tomcat8.0.38
Jdk1.8 hotspot vm
Mysql 5.7
Redis 2.7.3后端
首先进行主页测试,咱们访问tomcat的主页,使用jmeter的线程组中的线程数模拟用户数,不断增长线程数对主页进行性能测试。
咱们将结果数据写到一个xml文件中。首先咱们模拟5000个用户同时请求主页。缓存
设置循环次数为2,即一共有10000个请求将被发送。tomcat
从响应的结果能够看到,没有错误数,这10000个请求所有返回成功了,只是有的请求慢有的请求快。平均的响应时间在300ms, 50%的请求的响应时间平均为87ms。到后面愈来愈多的请求开始等待,这里能够想到的优化的点在于tomcat的线程池中线程的数量,愈来愈多的请求在等待队列中。查看tomcat的配置后发现最大线程数为maxThreads=”150”,好那咱们用150个线程,循环10次,也就是一共1500个请求,那结果会是什么样呢?并发
平均相应时间为5ms,前50%的请求的平均响应时间为1ms。
可是这里并不能直接修改tomcat的最大线程数来优化。复杂点说就是这是一个复杂的东西,线程数越大,你也要有相应的cpu来执行啊。直接点说就是,我不懂。。。
我把tomcat的线程数设置为500,而后起5000个线程发送10000个请求,而后获得了:性能
比以前的更差了。不管是平均相应时间仍是错误率。简单粗暴的去改线程数是不可行的。这里咱们不去管tomcat的线程数或者是其余层面的优化,咱们只专一于后端数据库层面的优化。测试
为何用500个,是为了减小由于tomcat请求等待带来的数据偏差。
直接向MySQL请求数据
先模拟500个用户,每一个用户发送10次请求。该请求相应的操做为根据id向数据库查询一条记录。获得了这样的数据。
期间打开windows的性能监控器,发现磁盘IO有变化,IO百分比最高的时候也不超过15%。
这样的操做,错误率为0,至关稳定,平均响应时间为1406ms。
磁盘的IO百分比一度达到了100%。从数据的绝对值来看,这样的测试没有意义了,由于瓶颈不在MySQL,瓶颈是tomcat的链接池最大线程数为maxThreads=”150” 愈来愈多的请求在等待队列中,由于咱们前面分析过的tomcat。可是数据的相对值是有意义的。
仍是模拟500个用户,每一个用户发送10次请求。
响应速度显著提升,注意一个值,Min=1,有些请求几乎不足1ms,由于redis直接从内存读取数值,很是快。若是不是tomcat的请求在排队,我想平均响应时间是个位数。
能够看到:模拟5000个用户比模拟500个用户的响应时间要慢不少,平均响应时间大概是8倍
能够看到,150个用户的话这种响应速度是比较快的,所以能够初步判定:响应的瓶颈在于tomcat的请求排队等待。
这个优化的过程我想到了不少东西,感受就是,优化是无止尽的。
好比,我想到了内存回收那一块。选用合适的垃圾收集器,尽量地减小GC时stop the world的时间和次数显然对于一个秒杀系统来讲是很是对的优化方向。这里我尝试用过几款垃圾收集器好比parNew,G1来对比他们的平均响应时间,可是屡次测试后没有明显的差距。有两个缘由,一是这个接口没有产生太多的大对象,二是这个优化并不太明显。后面有机会的话仍是但愿继续在内存方面进行优化,感受内存回收方面有点神秘,很想试一试。
能够看到redis的使用很大程度上提升了响应的时间。上面那个接口只是暴露一个地址,这些地址每一个产品都只有一个,那这样的场景是能够用redis的。可是有些操做并无办法使用缓存。好比执行秒杀这个操做。
这个操做是个事务型操做。若是其中一个操做失败了,我就让他rollback,这样的话,应该会有更多的并发问题。
见下篇。
原文连接:https://blog.csdn.net/OWEN_7/article/details/78319115