jmeter工具介绍
一、HTTP协议
协议是指计算机网络中,两台计算机之间进行通信所必须共同遵守的规定或规则。HTTP协议(是超文本传输协议HyperText Transfer Protocol),HTTP 协议是互联网应用中,客户端(浏览器)与服务器之间进行数据通信的一种协议。协议中规定了客户端应该按照什么格式给服务器发送请求同时也约定了服务端返回的响应结果应该是什么格式。
二、HTTP工作原理
根据HTTP协议的要求,无论是客户端发起请求,还是服务端返回响应,传输的数据都是以数据包的形式进行通信。一个数据包可以分成两部分:头(header)和身体(body)
HTTP请求头:
- host:目标域名或ip
- content-length:请求数据长度
- accept:客户端希望接受的数据类型,*/*代表所有类型
- user-agent:客户端使用什么工具去访问(浏览器)
- content-type:请求body中数据的类型,常见的有x-www-form-urlencoded代表表单页面,applicantion/json代表json字符串
- cookie:一些cookie信息
HTTP请求体(请求体中存放业务数据,通常两种格式):
- 键值对:loginName=admin&password=123456
- json{"loginName":"admin","password":"123456"}
HTTP响应头:
常见状态码:
- 200:正常
- 307:重定向,服务器要求客户端重新请求一个新的URL
- 401:未授权,需要身份认证
- 403:服务端禁止访问
- 404:请求的资源未找到,比如url错误,页面被删除
- 405:请求方法不允许,比如服务端是post类型,客户端使用get请求
- 500:服务端内部出现了异常
HTTP响应体:
响应体中包含了服务端返回的业务数据。数据格式可以是任何的文本内容,比如HTMLJson等,如果返回是HTML,浏览器会解析HTML并进行渲染,最终展示出期望的页面。
三、Jmeter简介
JMeter,一个100%的纯Java桌面应用,由Apache组织的开放源代码项目,它是功能和性能测试的工具。具有高可扩展性、支持Web(HTTP/HTTPS)、SOAP、FTP、JAVA等多种协议的特点。官方网站:https://jmeter.apache.org/
3.1 Jmeter安装与配置:
- 本机配置好Java环境变量
- 官网下载压缩包,在任意目录下解压
- 修改配置文件,打开Jmeter的bin目录下jmeter.properties,修改
- language=zh CN
- sampleresultdefault.encoding=utf-8
- 进入到Jmeter的bin目录下,双击jmeter.bat启动(mac是控制台进入bin目录,sh Jmeter启动)
3.2 Jmeter主要元件
- 测试计划
- 线程组
- 采样器
- 断言
- 监听器
3.3 Jmeter基本元件-线程组

3.4 响应断言
响应断言模式匹配规则
- 包括(Contains):如果响应中包含了指定的字符串,判断为成功,支持正则表达式
- 匹配(Matches):如果响应完全匹配指定的字符串,判断为成功,支持正则表达式
- 相等(Equals):如果响应完全匹配指定的字符串,判断为成功,不支持正则表达式
- 字符串(Substring):如果响应中包含了指定的字符串,判断为成功,不支持正则表达式(用得最多),多条件时可在测试模式添加多个条件,默认是且,如果要或者的关系,则在模式匹配规则勾选“或者”。
3.5 JSON断言
json路径表达式
$.code 代表json中的code字段值详细用法参见:https://github.com/json-path/JsonPath
四、Jmeter参数化
4.1 定义全局变量
测试计划-用户定义的变量(只初始化一次,放公共的固定的数据)

Jmeter中调用参数的方法:${ip}
4.2 常见的参数方式
- 生成随机数: __Random函数
-
生成随机字符串函数: _RandomString
- 计数器:线程组右键-配置元件-计数器,多个线程数时,不勾选“与每用户独立的跟踪计数器,则共用计数器次数,勾选则独立使用,当循环次数超过设置的最大线程数时,重新开始计数,用${引用名称}即可调用
-
从文本文件中读取数据:_CSVRead(文本文件,可以txt,csv格式的文件),按照线程来分配数据,每个线程分配一行数据,且无论这个线程循环多少次,永远使用的是同一行数据

- 添加CSV Data Set Config :线程组>添加→配置元件 >CSV Data Set Config ,与_CSVRead效果一致,都可以通过文件获取参数化变量,按照循环来分配数据,每次循环分配一行数据

五、后置处理器
5.1 JSON提取器:专门对ison数据进行提取的后置处理器
- 变量名称:自定义的变量名称
- json路径:JSON表达式
- 匹配数字:0代表随机,n代表具体的数字,-1代表所有
5.2正则表达式提取器:可以通过正则表达式来获取http请求返回的数据
- 引用名称:匹配后的结果,保存到一个参数中,如param
- 正则表达式:三步走
- 拷贝目标数据和左右边界
- 把目标数据用括号括起来
- 把目标数据用.+?代替
- 模板:$1$表示取匹配到的第一组数据
- 匹配数字:当某组数据中包含多少个参数时,0代表随机,1代表该组的第一个参数,2表示第2个。
六、Jmeter结果统计-聚合报告
- Throughput.吞吐量--默认情况下表示每秒完成的请求数(Request per Second)对于接口测试来说,Jmeter里的吞吐量=TPS

七、图形化插件的使用
7.1 图形化插件的使用
使用Jmeter插件可以扩展Jmeter的功能,插件官网:http://imeter-plugins.org/downloads/all,插件管理器使用方法如下:
- 下载插件管理器对应的jar包,然后放在Jmeter的lib/ext目录下
- 打开Jmeter,选项-插件管理器
- 勾选对应的插件,等待下载完成,点击apply,等待重启Jmeter,即可使用
几个好用的插件:
- Basic Graph:windows下可用的实时tps和响应时间的插件
- Custom JMeter Functions
- Random CSV Data Set Config
7.2 图形化插件的使用-TPS
- 添加tps监听器:事务控制器添加>监听器>jp@gc-Transaction per Second
7.3 图形化插件的使用-平均响应时间
- 添加tps监听器:事务控制器添加>监听器>jp@gc-Response Times Over Time
八、其他元器件
8.1 集合点
- 集合点是为了增加瞬间并发压力的一种机制,在脚本中增加一个标记,所有虚拟用户执行到标记处会进行等待,等所有用户都到达后,再同时继续执行下一步操作。
- 优点:对服务器来说,会产生一种瞬间高并发
- 缺点:对服务器来说,平均压力会降低
什么时候需要加集合点呢?
- 根据业务来选择,如果业务场景是瞬间高并发类型的,如抢购、秒杀等,需要加集合点;其他的场景都不需要加,一般加了集合点后,就不使用tps来衡量系统性能集合点功能要慎重选择,因为加了集合点后,系统的平均压力会降低
8.2 定时器
- Jmeter中的定时器类似于loadrunner中的pacing值和think time
- 定时器是在每个sampler(采样器)之前执行的,而不是之后
- 定时器是有作用域的;当执行一个sampler之前时,所有当前作用域内的定时器都会被执行。且所有的sampler执行前都会执行定时器
- 如果希望定时器仅应用于其中一个sampler,则把该定时器作为子节点加入
- 常用的定时器
- 固定定时器:设置一个固定的延迟时间,单位ms
- 同步定时器(synchronizing timer):在该定时器处,使线程等待,一直到指定的线程个数达到后,再一起释放。可以在瞬间制造出很大的压力。它和oadrunner的集合点差不多的功能
8.3 逻辑控制器
- 常用的逻辑控制器
- 循环控制器:可以设置该控制器内的sampler执行的次数,循环次数与线程的循环次数各自独立
- if控制器:根据判断条件决定是否执行该控制器内的请求,如果是字符串比较条件,参数和字符串都需要加引号
- 条件格式::${jex3(条件表达式)}
- 如:${jexl3(${num}>10)}、${ jexl3(“${num}”==“10”)}
- 仅一次控制器:该控制器内的请求只执行一次,无论线程循环多少次
8.4 配置元件-cookie管理器
- http cookie管理器:可以在浏览器中抓取到cookie信息,然后通过http cookie管理器为http请求添加cookie信息
- Jmeter的cookie处理机制和Loadrunner一样,Jmeter可以自动处理cookie,但是需要在线程组内添加一个空的cookie管理器
8.5 配置元件-header管理器
- http信息头管理器在http信息头管理器中添加一个或多个http请求header中的名称和值,可以修改请求头的值
8.6 上传和下载
- 上传:
- POST请求,勾选 use ...for post
- 同请求一起发送文件里,填写文件名称,参数名称
- MIME类型:application/octet-stream
- 下载:
- 普通GET请求
九、JDBC
JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序
- 在测试计划处添加驱动jar包
- 配置数据库链接信息:添加JDBCConnection Configuration,需要配置项:
- URL:jdbc:mysql://{ip}:port}/dbname}?useUnicode=true&characterEncoding=utf8

- 创建JDBC sampler
- SQL语句类型:select/update
- 执行方式分类
- 普通SQL:适合执行固定的数据
- 预编译SQL:sql语句中的动态数值用?代替,适合执行动态的数据,性能更好
- Parameter values:代替sql语句中的问号的数据
- Parameter types:数据库字段数据类型,如VARCHAR,INTEGER
- Variable Names:变量名称,跟SQL语句中查询字段数量保持一致
十、beanshell
- BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法,BeanShell是一种松散类型的脚本语言(这点和JS类似);
- BeanShell是用Java写成的,一个小型的、免费的、可以下载的、嵌入式的Java源代码解释器,具有对象脚本语言特性,非常精简的解释器iar文件大小为175k
- BeanShell执行标准Java语句和表达式,另外包括一些脚本命令和语法,
10.1 Jmeter常用的BeanShel
- 前置处理器:BeanShell PreProcesser
- 采样器:BeanShell Sampler 后置处理器:BeanShell PostProcesser断言:BeanShell断言
10.2 BeanShell内置变量
- 内置变量:beanshel脚本中不用定义,可以直接使用的变量,常用的内置变量和方法如下
- log:写日志到控制台和jmeterlog,如log.info(“xxxxx”);
- vars:操作jmeter变量
- vars.get(“skuld”);从jmeter中获取${skuld}变量的值
- vars.put(“name”” test”);将”test”保存到${name}变量中
- prev:获取前面sampler返回的信息
- getResponseDataAsString():获取响应信息
- getResponseCode():获取响应code
10.3 BeanShell-调用外部jar包
调用jar包
- 测试计划,Add directory or jar to classpath
- import 所需要的类名
import com.lee.util.Md5Util
String phone="135${ Random(10000000,99999999,myPhone)}"String code = "testfan"; // 生成随机手机号
String time="${time(,myTime)}"; // 生成时间戳
String md5 = Md5Util.getMd5Hex(phone+code+time); // 调用外部函数进行加密
vars.put("phone",phone); //将数据另存为新的变量
vars.put("md5",md5); //将数据另存为新的变量
10.4 BeanShell断言
- Failure:是否失败,boolean类型
- FailureMessage:失败日志,在断言失败时显示
int iStock= Integer.parselnt(vars.get("p stock"));
if (iStock > 1500){
Failure = true,
FailureMessage="库存数量超过了1500";
// ResponseData是服务器返回的byte[]类型的数据
// 如果想打印,必须转换为String类型的,用new String(ResponseData)
//打印当前请求的ur,SamplerData是String类型的数据
log.info(SamplerData);
}
10.5 Beanshell写数据到文件
- 调用登录接口,获取token值
- 将token值保存到一个文件里
String line = vars.get("userName")+","+vars.get(“token");
try {
BufferedWriter writer = new BufferedWriter(new FileWriter("c:lloutput.txt",true));
writer.write(line);
writer.newLine();
writer.close();}
}catch (lOException e) {
e.printStackTrace():
}
十一、线程数的意义
代表1个用户。Jmeter采用了线程来模拟用户,即1个线程个具体执行人。线程可以简单理解为计算机处理任务时的也可以由一个人(线程)来完成,但是至少需要一个人(线程)头来完成一个任务可以由多个人(线程)共同完成在线程组上设置线程数量为10,代表Jmeter会在瞬间启动10个线程来模拟10个用户发起请
十二、循环的意义
默认情况下,Jmeter里的每个线程(月户)只会发起一次请求,执行完成后Jmeter就会停止。这个时间通常很短。但是在实际场景中,大多数的业务都是持续不断的有用户来请求,这秒有10个用户系统能够支持短时间内的大量并发请求,但是持续一段时候来请求,下一秒还会有10个用户。好叫时,也必须让Jmeter持续的来模拟新的用户请求,这样才能可能就会挂掉。因此使用Jmeter来压更贴近实际场景。才能测出更多的问题程(用户)执行完一次请求后,还能继续执行请求,持续产Jmeter里可以设置循环次数,让一个经生压力。
- 循环方式一:设置固定循环次数
- 比如设置循环次数1000,代表每个线程连续执行1000次线程组内的请求,10个线程总共执行10000次请求。
- 循环方式二:设置固定循环时间
- 勾选永远,勾选调度器,设置持续时间,单位为秒。图中设置为180,代表持续每个线程持续执行180秒
十三、线程组的执行逻辑
- 在做脚本设计时,如果有多种业务同时压测,可以创建多个线程组,每个线程组上设置不同的线程数,线程组之间是相互独立的。线程组就代表了不同的人群。可以理解成线程组相当于是公司里的不同部门,每个部门有若干个员工(线程数),每个部门做的事情是相互独立的,互不影响。
- 如果某个业务需要调用多个接口来完成,通常会把多个接口写到同一个线程组内,代表了一个业务流程,比如“登录-加购物车-下单”。同一个线程组内的每个线程都会按照从上到下的顺序去执行请求,而且每个线程之间的工作也是相互独立。可以理解为销售部的每一个员工,他们在工作时,都会按照一个“寻找客户-忽悠客户-签合同”的顺序,每个员工都是在做自己的工作,有自己的客户,相互独立。
- 因为线程组上通常都设置了循环次数,因此每个线程执行完请求后,会继续循环下一轮,一直到循环结束。在销售部里面,每个员工签订完个客户后,会继续再次"寻找客户-忽悠客户-签合同"的流程。
十四、线程组和请求设置逻辑
- 一个线程组内的多个请求是顺序执行的
- 不同线程组内的请求是并行执行的
- 实际工作中如何设置线程组和请求的关系?
- 如果多个接口之间没有强依赖关系,每个接口单独设置一个线程组
- 如果多个接口之间有依赖关系(数据关联),把有关联关系的接口按照顺放在同一个线程组内
14.1 Jmeter基本元件-特殊的线程组
- setUp线程组执行全局初始化操作的线程组,在所有线程组前执行
- tearDown线程组执行全局结束操作的线程组,在所有线程组之后执行
十五、Jmeter命令行模式
Jmeter命令行模式-单机准备工作:
- 压力机安装并配置好JDK
- 在windows下调试好jmeter脚本,并上传至Linux下3、进到Jmeter 根目录下需要添加执行权限 chmod -R +x ./
- 单机器测试步骤:
- jmeter -n -t pinterjmx -l result.jtl
- -n:命令行模式,no-gu
- -t:jmx脚本路径
- -1:itl结果文件存放路径
- Controller和压力机
- 压力机:产生压力的机器,可以是windows系统或Linux系统
Jmeter命令行模式-分布式
分布式测试步骤:
系统HOSTS文件中进行类似 本机IP 主机名的配置,如10.0.0.23 zhoucentos,否则启动jmeter-server会报错
- 1,在每台机器上都部署 jmeter
- 2,如果是java脚本,将java脚本和相关lib包都放在jmeter目录lib/ext下
- 3,将jmeter的场景文件jmx上传到主jmeter的任意位置,参数文件放到每一台压力机上(存放目录要相同)4,每台机器修改jmeterproperties文件,ssl.disable=true(去掉注释)
- 5.在每台机器上进入到jmeter的bin目录下,都启动nohup ./jmeter-server&(后台启动jmeter-server服务
- 6,在主jmeter的bin目录下,修改jmeter.properties,将其中的remote hosts修改为作为压力机的两台机器ipremote hosts=127.0.0.1,192.168.0.102
- 7,在主jmeter的机器上,执行jmeter -n -t pinter.jmx -lresult.jtl -r(示例,具体目录和路径自定义)
注意:
1、脚本只需要放在主Jmeter机器上即可
2、如果有参数文件,需要在每台压力机上都放一份,且所在目录必须和脚本中配置的一致
Jmeter命令行模式-结果报表
三种方式来获取Jmeter的结果报表
、在GUI模式下跑Jmeter的脚本,用tps插件实时展示图表
二、在命令行模式下跑Jmeter的脚本,生成的itl文件,在GUI界面的聚合报告里打开,可以展示tps
和 响应时间等数据
三、在命令行模式下跑Jmeter的脚本,生成的jtl文件,通过Jmeter自带命令,生成html报表
注意:
在实际工作中,不推荐第一种执行方式,会影响Jmeter的性能,
Jmeter命令行模式-html报表
Html报表生成步骤:
1,进入jmeter的bin日录下,修改reportgeneratorproperties2,修改jmeterreportgenerator.overall granularity=1000(报表中数据展示间隔1秒)
3,创建一个存放数据报表的文件夹
4,执行命令:jmeter -g result,jtl -o ./output
其中:
-9 指定jtl文件的路径
-0 指定html报表生成到哪个文件夹下
Jmeter参数优化
1,控制台取样间隔的设置
summariser.interval=10,默认为30s,最低可修改为6s
2,Jvm参数优化
bin目录下,vi jmeter,修改HEAP的size大小,默认1024M,可以设置成2048M(前提是内存够)HEAP="-Xms2g -Xmx2g -XX:MaxMetaspaceSize=256m
3,默认编码修改
性能测试目的
测试系统最大处理能力
寻找系统最大的TPS,判断TPS和对应响应时司是否满足预期
测试系统支持最高并发
寻找系统最高能支持多少并发,当系统出现机、进程崩溃、报错率持续上升、响应时间超过可忍受范围、程的最高并发序无响应等情况,即可认为系统达到了可支持
sampleresult.default.encoding=UTF-8

浙公网安备 33010602011771号