性能测试工具JMeter

时间:2022-05-16 06:13:14

JMeter介绍
     Apache JMeter是Apache组织的开放源代码项目,具有极高的可扩展性,是一个100%纯Java桌面应用,用于压力/性能测试。JMeter可以用于测试静态或者动态资源的性能(文件、Servlets、Perl脚本、Java对象、数据库和查询、ftp服务器或者其他资源)。原先Jmemer是为Web/HTTP测试而设计的,但是它已经扩展以支持各种各样的测试模块。可以用来模拟对服务器或者网络系统加以重负荷以测试它的抗压能力,或者用来分析不同负荷类型下的运行情况。它提供了一个可替换的界面用来定制数据显示,测试同步及测试的创建和执行。
     JMeter最早是由Apache软件项目的开发工程师Stefano Mazzocchi 开发出来的。他当初开发JMeter主要用于测试Apache JServ(一个被Apache Tomcat工程取代了的项目)的性能。之后又再次设计了JMeter,增加了图形化界面和一些功能测试能力。 随着开发人员借助它的可嵌入的结构,JMeter的能力也随之快速的被扩大。更进一步的主要发展目标是把JMeter在没有减弱它的负载测试的能力的同时尽可能的做成最有效的回归测试工具。

JMeter的优缺点

优点:

开源免费、简单小巧、纯java开发可扩展、支持linux和windows

缺点:

无IP欺诈、报表类型少、上手比LR难、场景设置没有LR灵活、无进程模式、结果数据不是很准确(大并发时存在GC)、网上资料较少

1、JMeter安装与启动
    安装JMeter,只需简单的解压zip或tar文件到你想要安装的那个目录里即可。假定你已经正确的安装了一个JRE/JDK并且环境变量JAVA_HOME也已经被设置,那你则不需再做其它更多的事情了。JMeter可以在当前任何一个已经部署了Java的操作系统上运行---Unix(Solaris,Linux,etc)、Windows(98,NT,2000,XP)、Open VMS Alpha 7.3+
    启动JMeter,只需要执行bin目录下的脚本文件即可,包括如下脚本文件。
Windows脚本文件:
    jmeter.bat 运行JMeter(默认GUI模式)
    jmeter-n.cmd 加载一个JMX文件(jmeter脚本文件),并在非GUI模式下运行
    jmeter-n-r.cmd:加载一个JMX文件,并在远程非GUI模式下运行
    jmeter-t.cmd:加载一个JMX文件,并在GUI模式下运行
    jmeter-server.bat:以服务器模式启动JMeter
    mirror-server.cmd:在非GUI模式下启动JMeter镜像服务器
    shutdown.cmd:关闭一个非GUI实例(优雅的)
    stoptest.cmd:停止一个非GUI实例(中断式的)
Linux/Unix脚本文件:
    jmeter:运行JMeter(默认GUI模式,定义了一些JVM选项)
    jmeter-server:以服务器模式运行JMeter
    jmeter.sh:没有指定JVM选项的非常基础的jmeter脚本
    mirror-server.sh:在非GUI模式下启动JMeter镜像服务器
    shutdown.sh:关闭一个非GUI实例(优雅的)
    stoptest.sh:停止一个非GUI实例(中断式的)
当环境的JVM不支持某些JVM参数时,可以对jmeter脚本作必要的修改以适应环境的运行。

2、jmeter命令行选项
   JMeter在windows系统下启动的是一个Swing GUI界面,也可以在Linux/Unix系统中作为一个命令使用。调用JMeter的 “jmeter -?”命令将打印所有命令选项的一个列表。列表如下:
-h, --help 打印使用信息并退出
-v, --version 打印版本信息并推出
-p, --propfile {argument} 使用的JMeter属性文件
-q, --addprop {argument} 附加的属性文件
-t, --testfile {argument} 运行的jmeter测试文件(.jmx)
-l, --logfile {argument} 日志取样文件
-n, --nongui 非用户界面运行JMeter
-s, --server 运行JMeter服务器
-H, --proxyHost {argument} 设置JMeter使用的代理服务器
-P, --proxyPort {argument} 设置JMeter使用的代理服务器端口
-u, --username {argument} 设置JMeter使用的代理服务器用户名
-a, --password {argument} 设置JMeter使用的代理服务器密码
-J, --jmeterproperty {argument}={value} 定义附加的jmeter属性
-D, --systemproperty {argument}={value} 定义附加的System属性
-S, --systemPropertyFile {filename} 一个属性文件被做为系统属性添加
-L, --loglevel {argument}={value} 定义日志等级: [category=]level 例如jorphan=INFO or jmeter.util=DEBUG
-r, --runremote 从非用户界面模式启动远程服务器
-d, --homedir {argument} 使用的JMeter目录
-j,--jmeterlogfile {argument} the jmeter log file
-G,--globalproperty (argument)[=value] 定义一个JMeter属性并发往所有远程服务器。如:-Gport=123、-Gglobal.properties
-R,--remotestart serverl,... (non-GUI only) 在指定远程服务器上运行
-X,--remoteexit Exit the remote servers at end of test (non-GUI)

如:#jmeter -n -t test.jmx  --命令行执行测试,其中test.jmx为配置好并保存的测试计划

3、JMeter目录结构

     性能测试工具JMeter

1)bin目录:可执行文件(如:jmeter.bat)、配置文件(如:jmeter.properties)和日志文件(如:jmeter.log)等。
   2)docs目录:JMeter自身的一些java元素等。
   3)printable_docs目录:存放用户手册、一些脚本案例、HTML文件等。
   4)extras目录:提供对构建工具Ant的支持。
   5)lib目录:公共包,另外ext中存放JMeter的核心jar包(元件、补丁等),junit中存放JUnit测试脚本。用户扩展所依赖的包直接放在lib目录下。


JMeter相关概念

1、测试元件

测试计划:描述JMeter运行时将会执行的一系列步骤,包括一个或多个线程组、逻辑控制器、采样器、监听器、配置元件、断言等等,一个jmeter实例只包含一个默认的测试计划。
测试元件:JMeter的各种元素或部件的统称。
线程组:定义了一个虚拟用户池。一个测试计划的开始点,在一个测试计划中的所有元件都必须在某个线程组下。
逻辑控制器:控制jmeter脚本的执行顺序。
配置元件:设置一些jmeter脚本公共的消息,尽管它不能发送请求(HTTP代理服务器除外),但它可以补充或修改请求。
定时器:设置jmeter脚本与时间相关的信息,如:思考时间等。
前置处理器:采样器被执行前的前置处理。
Sampler:采样器,JMeter测试脚本的基础单元,向服务器发送某个类型(协议:HTTP、FTP、JDBC等等)的特定请求。
后置处理器:采样器被执行后的后置处理
断言:也就是检查点,验证服务器返回消息的。
监听器:收集以及展示测试结果的。
工作台:保存暂时不使用的测试元素,当保存一个测试计划时工作台的内容不会被保存。

JMeter 2.6版本支持如下采样器类型:(与现在最新的2.10版本有些差异)

性能测试工具JMeter

2、属性/变量/函数

JMeter属性:统一定义在jmeter.properties文件中,属性在测试脚本的任何地方都是可见的(全局)引用属性需要使用属性函数__P,如:${__P(group)}:返回属性group的值。
JMeter变量:JMeter变量作用域局限于所属线程。目的是让测试线程能够独立运转。有时候用户可能需要在不同线程间(可能属于同一个线程组,也可能不属于同一个线程组)传递变量。 其中一种方法就是使用属性。属性为所有JMeter线程所共享,因此当某个线程设置一个属性后,其他线程就可以读取更新后的值。如果存在大量数据需要在线程间传递,那么可以考虑使用文件。变量的引用如:${username},变量不支持嵌套引用,若要嵌套引用需要使用__V函数或__BeanShell。
JMeter函数:JMeter有很多的内置函数可用,通过函数助手也可以找到可用的函数以及生成函数引用。函数的引用与变量相同,如:${__time(EEE\,d MMM yyyy)}(逗号需要转义)

3、元件作用域规则
在jmeter中,元件的作用域是靠测试计划的的树型结构中元件的父子关系来确定的,作用域的原则是:
1)取样器(sampler)元件不和其它元件相互作用,因此不存在作用域的问题。
2)逻辑控制器(Logic Controller)元件只对其子节点中的取样器 和 逻辑控制器作用。
3)除取样器 和逻辑控制器 元件外,其他6类元件,如果是某个sampler的子节点,则该元件只对这个sampler的父子节点起作用。
4)除取样器和逻辑控制器元件外的其他6类元件,如果其父节点不是sampler,则其作用域是该元件父节点下的其他所有后代节点(包括子节点,子节点的子节点等)。
例子:

性能测试工具JMeter

该测试计划的元件包括取样器(HTTP请求1 、FTP请求2 、TCP取样器3),逻辑控制器(循环控制器), 监听器(图形结果1、聚合报告2)。作用域为:
   1) HTTP请求1 、FTP请求2 、TCP取样器3 元件没有作用域的概念。
   2)循环控制器 元件作用域名是其子节点FTP请求2 、TCP取样器3 。
   3)图形结果1 元件的作用域是是FTP请求2 、TCP取样器3。
   4)聚合报告2 元作的作用域是HTTP请求1 、FTP请求2 、TCP取样器3
   Jmeter中的逻辑控制器(Config Elements)在其作用范围内的行为与其他元件相比稍有不同。逻辑控制器元件分两大类:默认配置(HTTP默认请求、FTP默认请求等)和 管理(HTTP 头管理、HTTP cookie 管理等)。其中默认配置(Configuration Defaults)元件中设置的值可以在作用域内叠加,例如,在一个测试计划中添加两个HTTP 默认请求,其中第一个默认设置 Server name or IP 为www.google.com ,第二个默认设置Path 为/page-not-exist , 则在这两个元件作用域内的所有HTTP 默认请求,其默认的Server name or IP 和Path 均为Server name or IP和/page-not-exist。管理(Manager)类逻辑控制器元件的效果则不能进行叠加。如果两个或两个以上相同的管理类元件作用域有重叠。则在重叠作用域内的取样器元件只会随即受到其中一个的作用,这样会导致取样器行为的不确定性。因此,在使用管理类逻辑控制器时,一定要注意保证相同的管理类元件的作用域不发生重叠。

4、元件的执行顺序

元件执行顺序的规则很简单,在同一作用域名范围内,测试计划中的元件按照如下顺序执行。

1)配置元件(config elements )
    2)前置处理程序(Per-processors)
    3)定时器(timers )
    4)取样器(Sampler)
    5)后置处理程序(Post-processors) (除非Sampler 得到的返回结果为空)。
    6)断言(Assertions)(除非Sampler 得到的返回结果为空)。
    7)监听器(Listeners)(除非Sampler 得到的返回结果为空)。

关于执行顺序,有两点需要注意:
    * 前置处理器、后置处理器和断言等元件公能对 取样器作用,因此,如果在它们的作用域内没有任何取样器,则不会被执行。
    * 如果在同一作用域范围内有多个同一类型的元件,则这些元件按照它们在测试计划中的上下顺序一次执行。

 


使用JMeter进行性能测试---脚本配置

1、HTTP协议脚本录制
一、使用JMeter的代理服务器进行脚本录制
1)在工作台下新建一个HTTP代理服务器,设置代理端口、目标控制器(默认情况脚本会放在找到的第一个录制控制器下面,如果有的话)等参数并启动代理。

性能测试工具JMeter
2)(本地或远程机器上的)浏览器设置代理连接,完成业务操作即可。

性能测试工具JMeter

性能测试工具JMeter
     在脚本录制前可以先添加http默认值、用户自定义变量UDV、逻辑控制器等元件,录制的时候都会起作用。如要录制响应的话需要在工作台上添加的HTTP代理服务器下添加察看结果树监听器,另外该录制方式有些信息并不会添加到测试计划中,比如cookie、授权信息、上载文件等,所以录制完后需要自行添加cookie管理器、授权管理器等。

二、使用Badboy录制工具进行脚本录制
1)启动Badboy工具,新建一个测试,点击录制按钮,在Badboy中完成业务操作。

2)将录制到的脚本导出为jmeter脚本。

性能测试工具JMeter
3)启动JMeter工具,打开以上保存的脚本即可

性能测试工具JMeter

性能测试工具JMeter

目前发现通过Badboy录制的脚本,默认图片、CSS等资源请求不会被录制到。另外JMeter只支持HTTP协议的脚本录制,其他协议不支持录制需要手工进行配置。

2、参数化
1)使用用户自定义变量
   性能测试工具JMeter

性能测试工具JMeter

2)使用“函数助手”添加从文件中读取字符串的函数。
     通过菜单“选项”-->“函数助手对话框”调出“函数助手”,选择一个函数并生成函数的引用。比如选择“__StringFromFile”或“__CSVRead”,填写文件路径等所需参数,点击生成。然后拷贝函数引用字符串粘贴到需要替换的地方即可。“ 函数助手”保留最近一次生成的函数信息。

性能测试工具JMeter

性能测试工具JMeter

3)使用“CSV Data Set Config”配置元件
    性能测试工具JMeter

3、关联

1)在http请求下(提取关联值的请求)加入“后置处理器”>“正则表达式提取器”,引用名称即使用的参数名;填入正则表达式;模板选取匹配的组;匹配数字为匹配的个数,负数表示全部匹配;缺省值为没有匹配到时的取值。
    性能测试工具JMeter
    提取到的参数,调用时(置于使用关联值的地方)用${yzhxxx_1},${yzhxxx_2},${yzhxxx_3}……;如果想要得到匹配出的参数的个数,用${yzhxxx_matchNr};如果想随机选取其中一个,只需将匹配数字设为0,使用${yzhxxx}调用即可。可以一次匹配多组;示例中只匹配了一个,假如正则表达式为 name="chkProductIds"id="chk(.+?)" value="(.+?)",就会有两组参数。想获得匹配到的组个数用${yzhxxx_g}。

重要参数说明:

模板:如果前面的正则表达式取了不止一个参数(如 s0.id="(.*)";s0.ip="(.*)";),那么这里需要指定参数的组别,如果该参数为 $1$,则表示取得第一个值(id),$2$表示取得第二个值(ip)。

匹配数字:如果response中有多个地方都能够匹配s0.id="(.*)";s0.ip="(.*)";这个字符串,那么这里可以选择取第几次匹配,选择1表示第一次匹配,0表示随机,负数(-1)表示匹配所有值,依次类推。

2)在http请求下(提取关联值的请求)加入“后置处理器”>“XPath Extractor”。具体使用方式类似。

4、检查点(断言)

在脚本中添加“断言”-->“响应断言”,使用正则表达式进行检查,可以选择正则的模式匹配规则以及检查的文字段,也可以使用JMeter的函数引用,从外部文件中读取待检查的文本。
    性能测试工具JMeter
    如果要检查断言是否成功,需要添加断言结果监视器,当检视结果没有报错时说明断言成功,另外发现jmeter中的断言可以直接使用中文。

5、思考时间

在脚本中添加“定时器”-->“固定定时器”,设定延迟时间。定时器会让作用域内的每一个采样器都在执行前等待一个固定时长。
    性能测试工具JMeter

6、集合点

在脚本中添加“定时器”-->“Synchronizing Timer”,设置集合点处的并发用户数,即“多少”个用户达到集合点后再执行。
    性能测试工具JMeter

7、cookies

访问的页面需要cookies 时,在脚本中加入“配置元件”-->“HTTP Cookies管理器”,HTTP Cookies管理器会自动存储(没有再cookie管理器中展示出来不过可以从结果树中看到)和发送cookie,也可以手动添加一个cookie并被所有jmeter线程共享。
     性能测试工具JMeter


使用JMeter进行性能测试---场景配置

不像LR中那样测试脚本和测试场景是分开的,JMeter中测试脚本和测试场景融为一体的。一个测试计划就是一个完整的场景。

1、测试计划
    性能测试工具JMeter
   “独立运行每个线程组”:勾选以后所有的线程组都是顺序执行的了。一般不勾选,让所有的线程组并发启动。
   “函数测试模式”:勾选后会有详细的请求记录,消耗资源,影响客户端性能。一般不勾选。
   用户定义的变量:全局变量。

2、线程组

性能测试工具JMeter
    取样器错误后要执行的动作:继续,停止线程,停止测试。“ 停止线程”为停止当前的线程运行;“ 停止测试”为停止测试计划运行。
    线程数:可理解为当前线程组下脚本运行的“并发用户数”。
    RampUpPeriod (in seconds):开始运行时线程数在“设定的时间”内由 0 增加到设置值。RampUpPeriod 表示从0增加到指定线程数的时间,是线性增加,如:线程数为20个,RampUpPeriod为50s,50/20=2.5s/个,所以是每隔 2.5s 增加一个线程。
    循环次数:当前线程组下脚本运行循环次数;“ 永远”选项为无限次循环。勾选“永远”,启动后必须手工“停止”才会停止;次数达到时若调度器未运行完毕,则调度器无效,停止执行;调度器中运行完毕,次数尚未达到,则次数设置无效,停止执行。
    启动时间:脚本自动启动时间
    结束时间:脚本自动结束时间
    持续时间(秒):持续运行的时段
    启动延迟(秒):延迟指定时间后启动
    调度器:在手工启动后生效,设置生效原则:启动延迟的优先级高于启动时间,持续时间优先级高于结束时间,设置针对“未来时间”有效,针对“过去时间”无效;即启动延迟与启动时间同时设置如果不一致,则以启动延迟为准,持续时间与结束时间同时设置如果不一致,则以持续时间为准,设置为过去的时间则不生效。
在jmeter右上角显示线程运行状态。绿色表示正在运行;以及已启动的线程数和总的线程数。

 3、实现脚本逻辑(几个常用控制器)

1)If 控制器
    条件符合时执行控制器的子节点内容。
    性能测试工具JMeter
   示例:判断${is_run}=1 是否成立,如果成立就执行http请求;复选框“Evaluate for all children?”表示是否对所有子节点使用判断条件,不选择的话,只对第一个子节点生效。无else判断,可以用非条件来实现。

2)随机控制器
    随机执行某一个子节点内容。
    性能测试工具JMeter
    示例中随机控制器下有四个子节点:HTTP 1、HTTP 2、简单控制器、HTTP 3,简单控制器下有两个子节点:HTTP 3、HTTP 4;当复选框“忽略控制器块”未勾选时,简单控制器是作为一个节点跟其它随机控制器子节点一起参与随机执行;勾选时,简 单控制器下的子节点直接参与其它随机控制器子节点一起参与随机执行。

3)随机顺序控制器
    子节点全部执行,但顺序随机

4)循环控制器
    设置执行控制器子节点的次数,也可以设置永远执行。

4、观察执行结果(几个常用监控器)
    所有的监听器都保存同样的数据,唯一的区别是它们如何展示数据。多个取样器使用一个监视器时,得到的统计结果是累加起来的。

1)图形结果
    性能测试工具JMeter

样本数目:运行时得到的取样器响应结果个数
   最新样本:最近一个取样器结果的响应时间
   平均:所有取样器结果的响应时间平均值
   偏离:所有取样器结果的响应时间标准差
   吞吐量:每分钟响应的取样器结果个数
   中值:所有取样器结果的响应时间中间值
   显示图线为随时间变化曲线,但x轴不是时间轴,是取样器个数的均匀分布轴。

2)察看结果树---调试脚本时推荐只使用该监控器
    性能测试工具JMeter
   取样器结果:显示的是取样器相关参数(客户端参数与响应头)
   请求:http request
   响应数据:http response data 响应体

3)聚合报告---压测时推荐只使用该监控器
    性能测试工具JMeter
   Label:取样器名称
   Samples:运行时得到的取样器响应结果个数
   Average:所有取样器结果的响应时间平均值
   Median:所有取样器结果的响应时间中间值
   90%Line:所有取样器结果的响应时间 90%线
   Min:所有取样器结果的响应时间最小值
   Max:所有取样器结果的响应时间平均值
   Error%:出错的取样器结果占所有取样器结果的比例
   Throughput:每秒钟响应的取样器结果个数
   KB/sec:每分钟响应的数据流量
   点击下方的保存按钮可以将报告数据保存到文件。

4)Summary Report
    性能测试工具JMeter
   Label:取样器名称
   Samples:运行时得到的取样器响应结果个数
   Min:所有取样器结果的响应时间最小值
   Max:所有取样器结果的响应时间平均值
   Std.Dev.:所有取样器结果的响应时间标准差
   Error%:出错的取样器结果占所有取样器结果的比例
   Throughput:每秒钟响应的取样器结果个数
   KB/sec:每分钟响应的数据流量
   Avg.Bytes:所有取样器返回 http response data 字节数的平均值
   点击下方的保存按钮可以将报告数据保存到文件。