利用jmeter进行压力测试

jmeter进行压力测试html

推荐博客:jmeter  http://www.cnblogs.com/fnng/category/345478.htmljava

      http://www.cnblogs.com/puresoul/category/736960.htmlmysql

     javavirtualVM 远程  https://my.oschina.net/sub/blog/223475linux

     插件 http://blog.csdn.net/defonds/article/details/54576604ios

     调度器  http://blog.csdn.net/java2013liu/article/details/53424545web

1.压力测试的简单讲解sql

2.压力测试的指标、监控chrome

3.利用jmeter进行压力测试数据库

4.压力测试瓶颈的简单定位缓存

 

1.压力测试的简单讲解

  (1.)何时进行压力测试。

    基于接口的压力测试,在接口功能测试完成以后就可进行接口的压力测试。若是有接口的依赖关系,各个接口都要完成接口的功能测试以后,再行压力测试

    基于业务多场景的综合压力测试,要在全部业务功能测试经过以后进行

   (2.) 压力测试的合理性

    压力测试结果是否有效,还要看压力环境,举个例子: 测试环境和生产环境硬件配置没可比性,那么测试环境的压力测试毫无心义,测试报告毫无心义

    在没法保证测试环境生产环境相同的配置状况下,理论要求: 单机配置相同。再举个例子:正式环境服务器10台 16G 4核  数据库 5台   那么测试环境 1台 4核 16G的服务器,数据库服务器也要和生产单台配置相同

    若是有条件能够在生产环境直接进行压力测试

2.压力测试的指标   

一、吞吐率(Request per second)

服务器并发处理能力的量化描述,单位是reqs/s,指的是某个并发用户数单位时间内处理的请求数。某个并发用户数下单位时间内能处理的最大请求数,称之为最大吞吐率。

记住:吞吐率是基于并发用户数的。这句话表明,1:吞吐率和并发用户数相关;2:不一样的并发用户数下,吞吐率通常是不一样的。

计算公式:总请求数/处理完成这些请求数所花费的时间。

Request per second=Complete requests / Time Taken for tests

二、并发链接数(The number of concurrent connections)

并发链接数指的是某个时刻服务器所接收的请求数目,简单的讲,就是一个会话。

三、并发用户数(The number of concurrent users,Concurency Level)

要注意区分这个概念和并发链接数之间的区别,一个用户可能同时会产生多个会话,也即链接数。在Http/1.1下,IE7支持两个并发链接,IE8支持6个并发链接,FireFox3支持4个并发链接,因此相应的,咱们并发用户数就得除以这基数。

四、用户平均请求等待时间(Time per request)

计算方式:处理完成全部请求数所花费的时间/(总请求书/并发用户数),即

Time per request=Time Taken for tests/(Complete reuqests/Concurrency Level)

5:服务器平均请求等待时间(Time per request:across all concurrent requests)

计算公式:处理完成全部的请求数所花费的时间/总请求数,即

Time taken for/testsComplete requests

能够看到,它是吞吐率的倒数。

同时,它也等于用户请求等待时间/并发用户数,即

Time per request /Concurrency Level

 3. 利用jmeter进行压力测试

  1.参数化  2.关联   3.jmeter基本介绍  4.监控   5.测试报告

  @@@参数化@@@

在作测试时,造的测试数据要有本身的标识,便于之后删除或查找问题,好比:yxjtest001

对于LR或jmeter而言,本身输入的值顶多须要作参数化

参数化缘由:
1.逼不得已(应用程序不容许反复操做、数据库校验惟一性)
2.避免数据库的查询缓存
缘由:若使用线上(已有)数据或没有参数化,会致使测试结果失真。

查询缓存:

偷懒:
1.若数据量较大,可暂时把数据库校验惟一性去掉
2.为了消除缓存影响,可把数据库缓存(cache)关掉(对于select操做)

银行流水号-------参数化
100个并发用户,并发10分钟,tps=10,1个用户跑基准测试,tps=1
Q:参数化设置?
A:那么平均给每一个用户分配60个值,可是建议60以上好比80
(10*10*60/100=60,至少须要造的数据:60*100=6000)

银行流水号-------参数化
100个并发用户,并发10分钟,tps=?(无限),1个用户跑基准测试,tps=1
Q:参数化设置?
A:那么平均给每一个用户分配600个值,可是建议600以上好比800
(一个用户10分钟跑的事务:1*10*60=600,至少须要造的数据:600*100=60000)

关联函数放在距离最近的能够返回关联的值的那个请求的前面

    @@@关联@@@

将服务器返回的动态的变化的值,把他保存为一个参数,以供后面须要使用它的地方进行使用。

何时须要作关联:
1.服务器会校验该值的合法性【hash、cookie、session、token、时间戳、验证码(图片验证码、短信验证码、邮箱验证码)】
遇到 验证码 时,写js去本身解析验证码,而后再使用;
或者把验证码验证去掉(或整个万能验证码)
2.数据库打交道--后续须要对该值进行增删改查操做(此状况用的比较多)
insert操做---插入的值须要与其余表的数据创建关联/对应关系,须要进行关联

脚本回放成功,只是表明http状态码成功


查看关联函数放在哪儿,能够:
1.鼠标放在不肯定放在哪儿的脚本中,点击 tree-->http View 查看response
2.抓包看,找要关联的变化的值,看其在哪一个URL(即哪一个URL会返回该值)
3.点击 Run-time setting-->Log-->勾选 Data returned by server
4.看脚本下方的 Generation Log

关联函数添加:
1.进入Tree 模式,response下,找到要关联的值-->右键 Create Parameter
(此种方式关联的位置是对的,且会自动把左右边界找好,可是有可能左右边界值会错,因此须要回放看一下)
2.右键 insert-->new step (或者 alt+insert)||直接点击页面顶部的 insert-->new step
3.直接从response里面找
4.抓包,看里面的左右边界值
5.经过查看源文件,找左右边界值

>若是不转义,回放时系统会默认是HTML语言的一部分,进而把其忽略掉

若是左右边界设置的值不是很精确的话(即好多地方不一样的内容都匹配),系统默认取第一个取到的值,如果第一个值匹配的话还好,不匹配的话就会报错。

若是想要关联的值出现的次数较多,不肯定取哪一个值的左右边界时,建议取出现次数较多的。

批量替换:ctrl+h


【例子:】
登录天猫----查看首页----浏览商品---商品添加购物车---修改商品信息----删除不要的商品---支付---查看订单--删除订单

登录----可能须要参数化----select

查看首页--理论不须要参数化关联,精准推荐时候须要关联----select

浏览商品---有可能参数化 有可能关联 ----都是产品id----select

添加购物车---关联 商品id 用户id insert

修改商品信息---关联 商品id 用户id update

删除商品-----关联 商品id 用户id delete

支付-----insert订单 关联 订单id 用户id delete删购物车 关联商品id 用户id update 修改库存 商品id

查看订单----关联select 订单id

删除订单-----delete 关联 订单id

     @@@jmeter基本使用@@@

启用 调度器,则 循环次数 不生效

CSV Date Set Config中Allow quoted data?设置 True时取的值没有引号;设置 False时取的值有引号

CSV Date Set Config中Sharing mode----All threads:标准的 惟一 + 每次迭代
线程组与线程组之间取值也不同,严格遵循惟一
CSV Date Set Config中Sharing mode----Current thread:标准的 顺序 + 每次迭代
不一样线程组之间也是顺序的
CSV Date Set Config中Sharing mode----Current thread group:基于每一个线程组下的 惟一 + 每次迭代
不一样线程组之间是顺序的,平行取值

Loadrunner与Jmeter相比,Loadrunner靠谱。
Loadrunner响应时间比Jmeter小,由于是C写的。
小规模并发,jmeter响应时间比LR小一些,理论上LR响应时间比jmeter短,全部要加检查点,看请求是否都成功。
大规模并发,jmeter响应时间比LR大。

 

LR关联有5种方法:
tree视图response中找
tree视图里邮件自动关联
lr日志里找返回值
抓包
chrome中F12
查看源文件

Python最少学到IO操做

第1种自动化:测试工具的开发
第2种自动化:测试平台的开发

在作性能压测的时候,查看结果树通常被禁用,此时能够加【断言结果】,以此来查看请求是否成功。
【响应断言】结果在查看结果树里看

Jmeter中Think-time能够靠添加【定时器】来实现

Jmeter中集合点能够靠添加【Synchronizing Time】来实现

Jmeter查看报告的话,看【聚合报告】

跟随重定向,会记录整个请求过程,包括cookie跟header,自动重定向不会。

数据库链接池有2个,一个是MySQL容许的最大值,一个是应用程序容许的。主要是看应用程序容许的最大值是多少。
好比Jmeter中要看ax Number of Connections设置的值

开发测试的值跟你的不同(响应时间比你测的少,TPS比你的大)?
先肯定软件/硬件环境、数据库里的数据量是否一致,用的测试工具是否一致?
ab或webbench不接收服务器返回值,可是LR跟jmeter会接收服务器返回值,因此会不同。
即便用相同的工具,得出的值也会有所差别,可是不会差不少,能够取平均值。

工具里的响应时间是1.9秒,可是日志里响应时间是1.8秒?
先肯定大家的响应时间是否是指的【同一个】请求,由于工具里给的时间有多是多个请求的。

假设开发跟你看的都是一个请求,可是响应时间的值不同,是什么缘由?
开发计算的起始结束时间与你的不同,你的话能够从负载机、网络、中间件排查是否哪里中出了问题。

      @@@监控@@@@

CPU使用率高怎么办?
top命令看下CPU使用状况,而后按1看下是否全部的CPU都高,而后再看是因为刚并发致使的仍是并发一段时间后出现了该现象
接着看究竟是用户态进程占用CPU高仍是系统态进程占用CPU高,若是是user占用高则说明用户进程消耗了,
去查看高的进程(top),再去看进程对应的线程及执行的请求;
若是是系统态占用CPU高,说明系统内核调用致使了CPU比较高,
看是不是因为磁盘繁忙(sar、nmon--discuss busyness)致使的,
若是是磁盘的话再看是读仍是写致使的,如果读(磁盘往内存里读)说明有多是内存不足致使的,
如果写操做比较高看下是谁在写操做,查看下当前系统在写什么而后减小下写操做
若是不是由磁盘引发的,使用命令strace看系统调用的哪一个内核,

总结(CPU消耗高定位):
top 找出消耗最高的进程pid
top -H -p pid (找出最高的线程tid)
printf "%x\n" tid 线程tid转换成16进制B
而后拿着B去jstack dump出来的文件(nid)里查对应的方法
或者 jstack pid | grep 转换成的16进制

 

用户态cpu:用户进程作的事
系统态cpu:任何触发内核调用的

进程状态:running、终端可恢复状态、中断不可恢复状态、僵尸进程

top: load average-->指系统正在排队的进程已经进行的进程,简单来讲就是系统负载
(系统过去1分钟的平均负载、系统过去10分钟的平均负载、系统过去15分钟的平均负载)
查看cup颗粒数-->top后按1 或 cat /proc/cupinfo
Cpu(s)-->指平均CPU使用状况,不会超过100% || 可是Cpu却可能超过100%
Swap-->指虚拟内存
NI:指CPU运行进程的优先级
按CPU排序:shift+P
按内存排序:shift+M

load average:load---等待IO的进程+等待CPU处理的进程

CPU低,负载高状况:
IO操做进程比较多,等待IO的进程多
数据库全表扫描(没有索引时),由于数据不在内存在磁盘中,要从磁盘中那数据

存活区大约是大小相等,位置互换

YGC时执行2件事:
①. 寻根判断,判断哪些是垃圾对象,哪些是存活对象(没有引用的对象属于垃圾对象,还有引用的指向属于存活对象)。
②. 进行垃圾回收,把存活对象放到第一个存活区,把垃圾对象回收。(在进行垃圾回收时,整个应用程序的线程是暂停的。)

年轻代(仅仅供参考下,不全):
串行回收:java应用线程中止,用1颗CPU进行回收
并行回收:java应用线程中止,用多颗CPU进行回收

YGC只会发生在伊甸园区(伊甸园区触发YGC),可是YGC做用的范围是伊甸园区+存活区。

如下会进入老年代区:
1.大对象
2.长期存活的对象(默认age=15-->GC15次)
3.对象动态分配(survivor空间中相同年龄的对象的大小总和大于survivor空间的一半,则从该age及以上都会晋升到老年代)

老年代满了会触发FGC,可是年轻代与老年代不一样时作GC。

什么状况下会致使FGC?
1.定位内存泄漏用 jmap -dump的时候会触发FGC
2.老年代内存不足的时候
3.持久代被写满
4.System.gc()被显示调用
5.上一次GC以后Heap的各域分配策略动态变化

若是有大量的FGC就要查询是否有内存泄漏的问题了,若FGC数量比较大而且执行时间较长,就会致使系统的响应时间较长。

Full GC:
对整个堆进行整理,包括年轻代、老年代和持久代。
Full GC由于须要对整个堆进行回收,因此比YGC要慢(且会频繁占用线程),所以应该尽量减小、延缓FGC(老年代)的次数。

GC时,java应用线程是中止的,回收以后应用程序才会继续

jmap:分析内存泄漏,dump内存使用状况的
jmap -heap pid
jmap -histo pid 内存调用状况(能定位到方法级),若前几个没有本身认识的方法,
用MAT把内存信息dump下来
jmap -histo:live pid 内存中还在引用的对象
jmap -dump:live,format=b,file=XX.bin pid 能够dump堆内存使用快照
jmap -dump 的时候会进行(触发)FGC

jstat监视垃圾回收活动状况,看YGC时间是否是太长,FGC的频率是否过高,从而对代码进行优化
jstat -gcutil pid 2000 ---2秒刷新一下数据

jstack:把栈区dump下来,分析线程栈的时候:
先搜索是否有blocked(死锁)状态(若有blocked看死锁的线程执行的方法,进而找出缘由)
再看waiting状态(看waiting线程执行的方法,进而找出缘由)
再看running,像什么CPU高就是running形成的
jstack pid


总结(CPU消耗高定位):
top 找出消耗最高的进程pid
top -H -p pid (找出最高的线程tid)
printf "%x\n" tid 线程tid转换成16进制B
而后拿着B去jstack dump出来的文件(nid)里查对应的方法
或者 jstack pid | grep 转换成的16进制

 

线程ID转换为16进制格式:
printf "%x\n" tid

线程常见几种状态:runnable running wating sleeping blocked dead
进程几种状态:running 中断可恢复状态 中断不可恢复状态 僵尸进程

硬件缘由,好比CPU满或者负载很是高
用top命令查看cup、load average;iostat查看IO信息--若tps很低则表明IO没问题

【【日志要实时看,出了问题先看日志再使用top命令排除完硬件缘由后,应该立刻用jstack去看下线程栈】】
1.jstack 应用pid > XXX.log
2.看线程栈:vi XXX.log
3.搜索:/BLOCK 死锁缘由在 at 后

数据库死锁:表如今mysql里面block
线程池死锁:在线程池里面的锁就是线程池死锁

Jmeter 比 LoadRunner快的缘由:Jmeter有个长链接可勾选(User KeepAlive)

JVM参数--JVM内存大小默认64M好像是

定位内存泄漏最快的方式是用jmap
1.jmap -histo pid 内存调用状况(能定位到方法级),若前几个没有本身认识的方法,就用MAT把内存信息dump下来
2.jmap -histo pid > 1.txt
3.查看 1.txt,若在前20中没有发现认识的包/方法,就先dump一份(jmap -dump:live,format=b,file=XX.bin pid 能够dump堆内存使用快照)
4.而后sz XX.bin文件到Windows环境上,用MAT或jhat分析dump的文件,通常用MAT
5.使用MAT打开后会有2个窗口,不要看视图(Overview)而是先看报告就行

jmap -dump 的时候会进行(触发)FGC

jvisualvm dump的文件后缀是:.hprof

linux部署项目时,.war文件通常会自动解压,若系统没有给自动解压就用unzip手动解压便可

 

 

 

 

 

 

掌握JVM垃圾回收原理,可以熟练使用jmap、jstack、jhat、jstat、jconsole、jvisualvm、jprofiler 进行性能监控、问题定位及Java虚拟机的问题优化