jmeter(压力测试二)进阶-猫神
Jmeter接口性能测试(二)
一.jmeter内存溢出原因及解决方法
jmeter是一个java开发的开源性能测试工具,在性能测试中可支持模拟并发压测,但有时候当模拟并发请求较大或者脚本运行时间较长时,压力机会出现卡顿甚至报异常————内存溢出,内存溢出是指你应用的内存已经不能满足正常使用了,堆栈已经达到系统设置的最大值,进而导致崩溃,这事一种结果描述;
通常都是由于内存泄露导致堆栈内存不断增大,从而引发内存溢出。
在利用jmeter测试过程中,如果内存溢出的话,一般会出现这个提示:java.lang.OutOfMemoryError: Java heap space:意思就是堆内存溢出,不够用了。
内存溢出解决方法:调整堆内存大小
打开jmeter安装文件(可以用notepad++打开),bin目录下的jmeter.bat文件,找到set HEAP开头的内容,根据具体需要修改堆(heap)值大小,修改set HEAP=-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m 为
set HEAP=-Xms1g -Xmx1g -XX:MaxMetaspaceSize=2048m
堆的最大值不要超过物理内存的一半,否则容易导致jmeter运行变慢、卡顿甚至内存溢出
修改完成后,关闭文件,重启jmeter既可以
二.jmeter 分布式测试
有时候为了尽量模拟业务场景,需要模拟大量的并发请求,这个时候单台压力机就显得有心无力。针对这个情况,jmeter的解决方案是支持分布式压测,即将大量的模拟并发分配给
多台压力机,来满足这种大流量的并发请求场景。
原理:
1、分布式测试中,选择一台作为管理机(Contorller),其他的机器作为测试执行的代理机(Agent);
2、执行测试时,由Contorller通过命令行将测试脚本发给Agent,然后Agent执行测试(不需要启动GUI),同时将测试结果发送给Contorller;
3、测试完成,可以在Contorller上的监听器里面看到Agent发来的测试结果,结果为多个Agent测试结果汇总而成;
步骤
[if !supportLists]1) [endif]打开Contorller机下jmeter安装文件下的bin目录:jmeter.properties文件,搜索remote_hosts=127.0.0.1,将Agent机的IP和端口写在后面,比如:
remote_hosts=127.0.0.1,192.168.74.30:81,192.168.74.31:82
其中192.168.74.30和192.168.74.31为Agent机的IP,每个Agent机之间用英文半角逗号隔开,修改保存。
Contorller、Agent机中jmeter.properties文件中server.rmi.ssl.disable=true
2)在服务端(slave)安装目录的bin文件夹下执行jmeter-server.bat命令启动jmeter服务就可以,启动成功如下图:
启动jmeter-server.bat
注意事项
1、保持Contorller和Agent机器的JDK、jmeter以及插件等配置版本一致,host文件内容保持一致;
2、如果测试数据有用到CSV或者其他方式进行参数化,需要将data pools在每台Agent上复制一份,且读取路径必须保持一致;
3、确保Contorller和Agent机器在同一个子网里面;
4、检查防火墙是否被关闭,端口是否被占用(防火墙会影响脚本执行和测试结构收集,端口占用会导致Agent机报错);
5、分布式测试中,通过远程启动代理服务器,默认查看结果树中的响应数据为空,只有错误信息会被报回;
6、如果并发较高,建议将Contorller机设置为只启动测试脚本和收集汇总测试结果,在配置文件里去掉Contorller机的IP;
7、分布式测试中,如果1S启动100个模拟请求,有5个Agent机,那么需要将脚本的线程数设置为20,否则模拟请求数会变成500,和预期结果相差太大。
三.jmeter关联
一个完整的操作流程,需要先完成某个操作,获得某个值或数据信息,然后才能进行下一步的操作(也就是常说的关联/将上一个请求的响应结果作为下一个请求的参数);
在jmeter中,可以利用json表达式 、正则表达式提取器来帮助我们完成这一动作
选中接口→右键添加→后置处理器→json提取器
例:获取积分列表接口响应中user_id值 传给消费积分接口
积分列表响应:{
"code": 200,
"data": {
"stat": {
"all_point": "3100",
"all_money": "100"
},
"count": 1,
"list": [
{
"goods_info": null,
"mall": {
"address": "萍水西街7号",
"province": "浙江省",
"city": "杭州市",
"group_name": "",
"district": "拱墅区",
"name": "联华超市",
"is_cooperate": 1
},
"channel": "test",
"created_at": "2019-03-20T03:11:52.000Z",
"remark": null,
"user_grade": "Lv1",
"deleted_at": null,
"point": 3100,
"machine_code": null,
"trade_id": "07ce9951-000f-43d3-ab3f-844163b1dfa0_test",
"money": 100,
"updated_at": "2019-03-20T03:11:52.000Z",
"phone": "15603800797",
"user_id": 150,
"mall_id": 214,
"id": 66,
"is_use": 1
}
]
},
"message": ""
}
填写提取表达式设置变量
消费积分接口参数引用变量
成功获取
$.data.list[0].user_id,JSON中list 是一个对象数组, list[0] 代表取的是第一个数组的对象,
.data取的是data的值.list取的是list的值
响应非json格式 可可以用正则表达式提取器
[if !supportLists]四、[endif]测试活动
一个接口的参数传递依赖上一个接口的响应两个接口之间需要加入间隔时间
使用测试活动组件
线程组--添加取样器--测试活动
Duration值为300 意思为 A接口完成请求响应后300ms,提取到响应中userid传给B接口
五、有时候工作中我们需要对数据库发起请求或者对数据库施加压力,那么这时候就需要用到JDBC Request
JDBC Request可以向数据库发送一个请求(sql语句),一般它需要配合JDBC Connection
线程组上面右键单击选择配置元件→ JDBC Connection
设置好JDBC连接配置后,添加JDBC请求,界面如下:
写要测试的sql语句
运行查看结果
六、websocke接口接口测试
线程组-添加取样器-WebSocket Sampler
[if !supportLists]1. [endif]Streaming Connection – 选择这个TCP session要不要保持,如果勾上标识连接会一直存在,如果没有勾上,那么得到第一次响应后该链接就会被关闭
[if !supportLists]2. [endif]ws与wss, ws前缀是WebSocket连接的辨别标识,wss前缀是WebSocket安全连接的辨别标识。根据自己的实际情况填写
Response Pattern – 采样器将等待含有该标识的消息并继续通信(或者直到timeout,该连接关闭)4.Close Connection Pattern – 如果服务器返回的消息含有这样的字符,就结束会话。5.Message Backlog – 定义服务器返回消息保留的最大长度。
[if !supportLists]七. [endif]dubbo接口测试
jmeter本身并不支持dubbo接口的测试,需要下载第三方插件,然后将jar包放入jmeter\lib\ext路径下,重启即可。
下载dubbo测试插件
下载地址
启动jmeter
添加线程组→Sampler→Listener,dubbo-sample界面如下
各参数说明如下:
Protocol:注册协议,包括zookeeper、multicast、Redis、simple;
Address:注册地址,dubbo服务的IP+Port:
①、当使用zk,address填入zk地址,集群地址使用","分隔;
②、使用dubbo直连,address填写直连地址和服务端口;
Protocol:使用的dubbo协议,包括dubbo、rmi、hessian、webservice、memcached、redis,根据自己的协议类型选择对应的选项即可;
Timeout:请求超时时间,单位ms,根据dubbo具体配置填写;
Version:版本,dubbo不同版本之间差异较大,不同版本之间不能互相调用,这里指定dubbo版本,是为了方便识别和说明;
Retries:异常重试次数(类似这种分布式服务通信框架,大多都有重试机制,是为了保证事务成功率);
Cluster:集群类型,包括failover、failfast、failsafe、failback、failking;
Group:组类型,如果有的话,根据配置填写即可;
Connections:连接数,同上,根据配置填写;
Async:服务处理类型,包括sync(同步)、async(异步),根据配置填写;
Loadbalance:负载均衡策略,包括random(随机)、roundrobin(轮询)、leastactive(最少活跃数)、consistenthash(一致性哈希);
Interface:接口名(因为dubbo服务大多是开发根据规范自行命名的,因此这里需要填写完整的接口名+包名);
Method:当前接口下的方法名,按照开发提供的API文档填写即可;
Args:接口报文,根据API文档填写,如上图所示,添加输入行,输入对应的参数类型和值即可(参数类型和值如何定义填写,请参考上面的链接);
①、paramType:参数支持任何类型,包装类直接使用java.lang下的包装类,小类型使用:int、float、shot、double、long、byte、boolean、char,自定义类使用类完全名称;
②、paramValue:基础包装类和基础小类型直接使用值,例如:int为1,boolean为true等,自定义类与List或者Map等使用json格式数据;
[if !supportLists]8. [endif]函数助手
函数助手的话,可以按照规则生成一些参数,比如说随机数取当前时间,最常用的就是这两种。
随机数__Random,可以在你指定的一个范围内取随机值
取当前时间__time,如果在有一些需要传时间的情况下可以使用,日期格式是:yyyy-MM-dd HH:mm:ss 年-月-日-小时:分钟:秒
取唯一id,__UUID,这个就是每次会生成一个随机的uuid,都是唯一的。