大家好,我是IT修真院北京分院第32期学员,一枚正直善良的程序员,今天给大家分享一下如何用Jmeter对自己的服务器进行有效压测,让服务器效果最优化:
一、Jmeter
Jmeter是一个全部代码由java组成的测试软件,主要用来测试服务器的并发数、响应时间、吞吐量,界面如下:
我们可以自己写一些http请求,也可以使用其他辅助工具来完成脚本的录制,这里推荐一款录制脚本软件Badboy,导出jmx文件放入Jmeter软件中可以直接出现如上图的step1、step2,然后将就可以运行。
既然要进行压力测试那么我们就要明白一些参数的实际意义,
(1)Jmeter的测试参数:
线程数:本机与测试网站建立的连接数,因为还有一个等待时间所以线程数未必是顺发
等待时间:我自己的理解是在X秒之后最后一个线程启动,来画一张图理解一下:
我们可以把这些看成是我们的线程,在没有循环的情况下,一个链接从开始到结束即收到数据之后就会停止,如果我们想保持我们的并发量,就需要设置合理的循环次数和等待时间,使我们的服务器在中间一段时间内可以保持全部线程并发来达到一个合理的测试结果。
循环次数:就是每个线程的循环次数,这里有个坑,如果你使用了badboy录制脚本,step中有个循环次数
我们需要调整这个循环次数而不是最开始图上的循环次数,那个循环次数对step无效。
调度器:方便我们自动化测试脚本,启动时间和持续时间从字面可以理解意思,我在这里没有使用调度器就不妄加评论。
(2)聚合报告的参数:
samples:这个该是请求次数
average、median:平均时间和中间时间
90%line、95%line、99%line:先明确一下xx%line的含义,即百分位,如果100个请求按时间升序排列,我是第90个,那么我请求的时间就是90%,翻译过来就是有90%的数据花费的时间比我的少,这个指标代表了高并发情况下大部分用户的体验值
min、max:最短耗时和最长耗时 也就是第一位和第一百位,以上时间均以毫秒位单位
error:状态码不为200的请求(错误请求),原因有很多,可以具体查看。
throughput:吞吐量,每秒钟处理请求的次数
recieved kb/s:获得的数据量
比较重要的是90%line、error、throughput,我们在做压力测试的时候要根据服务器和网页的实际情况,不只根据数据还要根据服务器的性能来做出各种调整,需要注意的是不是tps越高越好,也不是90%线越快越好,因为这无法代表你服务器的最佳状态,参数需要多次调式之后才能获得正确聚合报告。
(3)Jmeter的插件
Jmeter自带的一些图像可能无法满足我们的需求,这里可以使用Jmeter的插件,Jmeter Plugins下载一些方便我们测试的插件,如下图:
在此测试中我主要使用的是聚合报告、jp@gc - Transactions per Second和结果树三个报告。
二、实际测试
下面是我要测试的三个页面:
主页:主页包含大量的静态文件,极少的和数据库交互的动态数据,只有4个随机选取展示学生会比较浪费时间。
学生列表页面,此页面无静态资源、直接从数据库拿出一个100数据的大list。
学生查询页面,此页面只有一组数据,memcached进行的是key-string缓存、redis进行的是key-map缓存。
(1)主页压测结果:
无缓存、无动静分离,无负载均衡:
memcached缓存、有动静分离、无负载均衡(15线程、20循环、4次样本):
服务器带宽情况:
memcached缓存、有动静分离、有负载均衡(15线程、20循环、4次样本):
服务器带宽情况:
redis缓存、有动静分离、有负载均衡(15线程、20循环、4次样本):
top指令查看服务器内存、CPU占用情况:
服务器带宽情况:
redis缓存、有动静分离、无负载均衡(15线程、20循环、4次样本):
服务器(1M)带宽情况:
redis缓存、有动静分离、有负载均衡(15线程、20循环、4次样本):
(2)学生列表(100个)压测结果:
无缓存、无负载均衡(15线程、20循环、4次样本):
memcached缓存、有负载均衡(15线程、20循环、4次样本):
服务器(1M)带宽情况:
memcached缓存、无负载均衡(15线程、20循环、4次样本):
服务器(1M)带宽情况:
redis缓存、无负载均衡(15线程、20循环、4次样本):
redis缓存、无负载均衡(20线程、20循环、1次样本):
服务器(1M)带宽情况:
redis缓存,有负载均衡(15线程、20循环、4次样本):
服务器(1M)带宽情况:
(3)查询单个学生压测结果:
无缓存、无负载均衡(20线程、50循环、6次样本):
memcached缓存,无负载均衡(20线程、50循环、6次样本):
服务器(1M)带宽情况:
memcached缓存,有负载均衡(20线程、50循环、6次样本):
服务器(1M)带宽情况:
redis缓存,无负载均衡(20线程、50循环,6次样本):
服务器(1M)带宽情况:
redis缓存、有负载均衡(20线程、50循环、6次样本):
服务器(1M)带宽情况:
测试总结:
在合适的线程*循环数的情况下服务器带宽均能跑到0.9-1.1,这里也是一个最大的瓶颈,网络因素也最大程度的影响了测试结果,下面分析一下测试报告:
(1)主页
由于主页的特殊性,缓存与否影响不大,甚至可能会造成速度减慢,重点应该放在负载均衡与动静分离的处理上:
此处没有做无动静分离的情况,因为一开始没有动静分离15*20有的时候都跑不完。
如上图所测,在无负载均衡的情况下,吞吐量只有1.8,每秒接受数据量33.26,90% 2138
在有负载均衡的情况下,吞吐量均达到了5以上,每秒接受数据量90-100,然而90%变慢,相应的90%-100%之间的速度大大提升,速度加快一倍
结论:在大量静态页面+少量动态数据的构成页面中,我们可以只配置动静分离+负载均衡就能大幅度的提高服务器吞吐量,但是90%线会稍微变慢,相应的,90%-100%速度会大幅度加快,而缓存对这种页面影响十分小。
(2)100个对象的list
无负载均衡、无缓存:90% 3244 TPS:2.9
无负载均衡、memcached缓存:90%:2273 TPS:5.2
无负载均衡、redis缓存:90%:2195 TPS:5.0
可以看出缓存的效果,90%线减少,TPS增大明显,但是这里有一点要说,虽然redis缓存90%线低于memcached90%线,但是90%-100%的处理时间要比memcached稍微长一些,不能排除是网络因素导致。
负载均衡对此处的影响:
memcached:90%增加,95%增加,99%减少,吞吐量5.2-5.8,略微增加
redis:90%不变,95%不变,99%减少,吞吐量5.0-4.7,略微减少
结论:在查询大量数据的时候,应该使用缓存,但是也要考虑缓存序列化与反序列化消耗的时间,也要善于利用redis的map存储特性,负载均衡对此处影响不大,而且网络有波动会对测试结果造成很大的影响,不能断言负载均衡的效果,结合服务器的负载情况,当开启两个tomcat部署项目的时候内存消耗分别为30%和20%应该还有很大提升空间,但是受限于1M带宽。
(3)单独查询一个学生
无负载均衡无缓存:90%:218 TPS:104.3
memcached缓存:90%:219 TPS:118
redis缓存: 90%:224 TPS:62
结论:此处redis做了map缓存导致pojo类和map类转换(反射过程)消耗了大量时间,tps明显降低,而使用memcached则是直接存储String类型,90%无变化(数值太小),TPS略微上升,对小数据的缓存我们应该谨慎使用,但是还是建议使用redis和memcached的普通类型存储,而不建议使用map。
负载均衡对此处的影响:
memcached:90%线无变化,TPS降低
redis:90%线无变化,TPS上升:62.2-84.7
结论:负载均衡下分担了POJO-MAP及MAP-POJO的转换压力,加快了速度,但是吞吐量还是比不上直接存储的速度,但是memcached这个降低没太搞懂。
(4)缓存穿透:模拟失败,设置为空的时候查询不存在的key,90%线差不多为40,TPS200多,但是没有穿透情况下的数据,原因为各种环境因素制约。
(5)在维护数据的同时查询:由于没有使用互斥锁,查询到了脏数据的情况。