返回 登录
0

JMeter常见问题

阅读2940

本文列举的性能测试人员常见的一些问题,重在思路。思路再辅以工具自然非常方便地解决问题。

作为一个性能测试人员对于问题要勇于分析,不要逃避问题,在网络上总有一些网友问一些常识性的问题,这都是学习态度问题,不能够沉下心来对问题进行分析,对涉及的知识不进行补充,指望别人帮忙,这种浮躁的学习心态要不得。
下列问题在《全栈性能测试修炼宝典 JMeter实战》中的第15章中做了摘选,只选了前10个问题。

1 JMeter无法开启

Windows下双击%JMETER_HOME%/bin/jmeter.bat时无法启动JMeter,如图15-1显示。

图片 1077{340}

图15-1 JMeter启动报错

此问题是没有配置Java环境变量JAVA_HOME,图15-2所示是在Windows 7高级系统设置中配置环境变量。

图片 1078{284}

图15-2 Windows 7 JAVA_HOME配置

图15-3所示是在Linux下找到/.bashrc文件进行配置。

图片 1080{361}

图15-3 Centos JAVA_HOME配置

2 JMeter异常关闭

有时候在运行JMeter的过程中突然JMeter崩溃,这种异常关闭的情况多数是由于内存溢出的原因,在不设置JVM Heap大小的情况下,默认是512MB。如图15-4所示是JMeter 2.13版本的默认设置,文件在%JMETER_HOME%/bin/jmeter.bat中。

图片 1095{450}

图15-4 JMeter默认JVM设置

可以根据实际情况适当加大,如果你的计算机有4GB以上的可用内存且是64位系统,建议把-Xms与-Xmx都设置成2GB,其他参数都不用改变。

3 JMeter无法产生负载

在使用JMeter进行脚本开发及运行时偶尔会遇到无法生成负载的情况,此时大家要注意检查各元件是否是禁用状态。JMeter运行时是以tree的形式加载各种元件,如果父结点被禁用,那么其下的所有子节点也将不能运行。如图15-5所示测试计划中线程组被禁用,虽然下面的元件没被禁用,但运行时根本就无法产生负载,但JMeter并不会报错。

4 JMeter日志输出控制

我们知道日志输出(IO)可能会导致瓶颈,当我们用JMeter来模拟负载时,JMeter默认也会写一些日志。虽然日志方便我们在出错时查找问题,但有一些日志并不是我们想看的,比如一些Debug及INFO级别的日志,我们并不关心;但这些日志太多的情况下会影响JMeter的效率,建议提高日志级别,只记录Error日志。

JMeter日志控制在%JMETER_HOME%/bin/jmeter.properties文件中进行修改,如图15-6所示默认的日志级别是INFO,这里的日志设置主要是针对JMeter原有组件。如果你没有对JMeter进行过扩展,那么你只要修改此处的配置即可以控制JMeter的日志输出;如果你扩展过JMeter Sampler,比如在Java Sampler中扩展了一个测试类且有自己的包名,那么想要控制此类的日志输出,就需要配上包名,如你的扩展测试类包名是com.road.test,那么你可以配置 log.level.com.road.test=Error,只记录错误日志。

图片 9410{292}

图15-6 日志控制

5 记录测试结果影响JMeter效率

性能测试时我们对负载机器的性能也要加以关注,避免因为负载机的性能问题而不能产生足够的负载。在运行大量负载(大量线程)时测试结果记录会很多,而保存到文本文件的操作是同步的,线程之间自然会有排队,如果IO量大,负载机磁盘也将会面临IO瓶颈风险,从而拖慢JMeter,导致产生的负载变小。所以我们要以最小的代价来存储更少的测试结果,采用的基本方法如下。

(1)不记录测试结果到文件,非GUI方式运行时标准输出结果如图15-7所示。

图片 9418{426}

图15-7 日志控制

以GUI方式运行时,可以直接在聚合报告或者Summary Report中查看到测试结果。

(2)以CSV格式记录,不要以XML格式记录。JMeter 2.13默认是以CSV格式记录,此设置也是在jmeter.properties中进行配置,其中有一项目:jmeter.save.saveservice.output_format=csv。

另外对于记录哪些结果字段也是可以设置的,尽量记录更少的字段,如图15-8所示是默认记录的字段,建议去掉“Save Response Message”“Save Assertion Result(XML)”与“Save Sub Results(XML)”。

(3)不要重复记录测试结果,图15-8中把测试记录记录到D:\result.jtl文件,其他的监控器元件就不要再记录,不然会重复记录。

注:上面说到记录测试结果可能会影响JMeter效率,那么会不会对测试结果产生影响呢?

当然会,由于负载变小,所以服务器面临的压力相对变小,TPS就有可能没有到拐点。此时我们需要更多的JMeter实例来模拟负载。另外要说明的是,虽然影响JMeter效率,但对于响应时间来说影响会比较小,通常可以忽略。

6 JMeter可以测试接口吗

经常被学员问到这个问题。接口范围太广,常见的有HTTP协议、Socket协议、WebSocket协议、WebService(Soap)协议等。可以肯定的是以上协议都支持,只要构造好表单,在JMeter中用相应的Sampler就可以模拟出请求。经过笔者的了解与统计,这样问的学员基本上都是对协议不了解,磨刀不误砍柴工,打铁还需自身硬,提高自己是必要的。

7 JMeter可以测试Dubbo接口吗

不少业内的测试同行在网上问我Dubbo协议如何进行性能测试,想必这些同行的公司也应该是互联网公司,系统采用SOA架构,微服务化,分布式化。Dubbo是阿里巴巴的梁飞及其团队推出的开源服务框架,用者甚多(某企业在此基础上推出了Dubbox),官方也给出一个测试示例,大家完全可以参照这个示例进行测试。

看过示例就会发现这东西在JMeter中没有,JMeter不支持Dubbo协议接口的测试,需要自己二次开发扩展。

接着会有人抱怨,每个接口都要写程序,其实我们可以懒一点,可以开发一个组件自动识别这些接口就可以了。所以笔者就开发了一个这样的组件,是基于JMeter来扩展的(1.6节中有个图就是展示这个组件),功能测试可以用,自动化测试可以用,性能测试也可以用,三合一。用Dubbo框架的同行你们公司Dubbo接口的功能测试是如何进行的?

(1)转成WebService协议;

(2)转成Restful风格;

(3)开发一个界面。

是不是被我说中了呢?联系Road获取Dubbo测试组件,Dubbo测试效率就上去了。

下面是JMeter Dubbo Sampler示例。

(1)打开JMeter,建立一个测试计划,如图15-9所示。

(2)选中【线程组】,单击鼠标右键找到Sampler下的DubboSamper,单击添加此元件,如图15-10所示。

图片{276}

{-:-} 图15-9 建立测试计划

图片 6{262}

{-:-} 图15-10 添加Dubbo Sampler

(3)编辑测试用例,如图15-11中dubbo application即是应用名,与配置文件中对应。

dubbo servicename 与配置文件中的interface对应。

dubbo method name 即是接口中定义的方法名。

图片 8{452}

图15-11 编辑测试用例

(4)参数化。

① 单击【init servies】,实际上此时开始从zk获取context,只需要单击一次,只要JMeter不关闭,context一直驻留内存。

② 单击【Get Json Template】,生成一个表单示例,用户根据这个提示进行参数化,注意“[]”这一对中括号不要省略掉。图15-11中的[23]是参数化一个int型变量。

(5)执行用例。

① 先添加一个查看结果树元件,方便查看测试结果。

② 直接单击图片 9{15}运行当前测试用例。

8 JMeter可以测试RPC接口吗

上面提到的Dubbo就集成了RPC功能,对于分布式服务框架来说RPC是必须的。现在越来越多的企业用到分布式,测试自然也免不了。

JMeter中没有组件提供RPC的调用,JMeter原生版本不支持RPC的接口调用。参照Dubbo,这也需要自己开发组件去完成。组件的原理就是通过反射来获取接口服务,然后从GUI界面获取到参数,通过反射来执行方法。当然在开发过程中为了提高程序效率会涉及一些设计模式,比如单例。不会开发怎么办?同样可以联系Road获取帮助。

9 JMeter函数助手中函数不够用怎么办

在编写脚本的过程中我们经常会碰到要构造一个创建时间或者有效时间,这些时间与当前时间会有一个偏移量,而且这些时间在性能测试执行时要求是动态变化的。

于是我们会打开JMeter的函数助手,最后我们找到的好用的函数就是__time这个函数,此函数的使用是构造一个当前时间,可以指定输出格式,如图12所示,具体用法请参照6.8.29节。

遗憾的是这并不能满足咱们的要求,我们要求有一个偏移量。如何解决这类问题呢?通常的方法有。

(1)使用BeanShell来构造一个时间变量,如图15-13,使用BeanShell PreProcessor来构造两个参数(orderDate、senderDate),分别是当前日期往后偏移一天和二天。当然使用BeanShell sampler同样也可以完成此工作。

图片 1{511}

图15-12 JMeter __time()函数

图片 27{350}

图15-13 JMeter BeanShell PreProcessor

(2)上面使用BeanShell实际上类似于在写Java代码,每个脚本重复这样的工作浪费时间。既然写程序就要把重复的事情抽象出来、封装起来,提供API供调用。基于此想法,我们是不是可以给JMeter增加函数?当然可以,打开JMeter源码,如图15-14中org.apache.jmeter.functions包中全部是JMeter提供的函数,大家只需要参考这些源码模仿着写即可,把上面的BeanShell脚本搬到Java代码中去。

图15-15我们建立了一个Offset函数,用来获取偏移后的时间,我们只需要覆写下面框内的方法,主要实现就是execute方法,execute中的代码如下,读者可以参考一下。

图片 1{226}

{-:-} 图15-14 JMeter函数源码

{-:-}图片 1{284}

{-:-} 图15-15 Offset函数方法目录

execute方法覆写

@Override
     public String execute(SampleResult previousResult, Sampler currentSampler)
                throws InvalidVariableException {
                Date datetime = new Date();
                String dateRt;
             if (format.length() > 0){
                 String fmt = aliases.get(format);
                 if (fmt == null) {
                     fmt = format;
                 }          
             }
             //获取当前时间的偏移量,比如当前时间往后推7天
             int off = Integer.valueOf(offset);
             Calendar cal = Calendar.getInstance();
             SimpleDateFormat  sdf = new SimpleDateFormat(format);
             try {
                         cal.setTime(sdf.parse(sdf.format(datetime)));
               } catch (ParseException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 }
            cal.add(Calendar.DAY_OF_YEAR,off);
            dateRt = sdf.format(cal.getTime());
             if (variable.length() > 0) {
                 JMeterVariables vars = getVariables();
                 if (vars != null){
                     vars.put(variable, dateRt);
                 }
             }
             return dateRt;
     }

其他方法的覆写参照TimeFunction,剩下的就是打包发布到JMeter的lib/ext目录下面,然后重启JMeter就可以在函数助手中看到你的函数。图15-16中可以看到__offsettime函数,它有3个入参,time format是指定输出格式,offset save in parameter是把偏移后的时间存到变量中去,其他的Sampler可以调用,offset value是偏移量,相对于当前时间的偏移量。调用格式如下:{__offsettime(yyyy-MM-dd,offsettime,10)},offsettime是变量,其他Sampler又可以调用,调用格式是{offsettime}。

图片 1{371}

图15-16 __offsettime函数对话框

10 JMeter支持子事务的定义吗

有时候我们会把一个大的事务拆分成几个小的事务来计算其响应时间,更利于去分析问题,那么JMeter支不支持子事务呢?

肯定回答JMeter可以支持子事务,只是实现方式与LoadRunner不一样。JMeter有一个事务控制器,放在其节点下面的Sampler都会以子事务来统计,事务控制器会把节点下所有Sampler的事务时间合计在一起。

图15-17中Java请求1与Java请求2的Average时间之和就是Java请求的Average。

图片 1{494}

图15-17 Summary Report

在JMeter的设计中,Summary Report是可以准备支持子事务的,只是有了事务控制器这个设计就不必要了,图15-18中笔者修改了源代码,使其支持子事务,此修改适用于JavaSampler元件。

图片 1{404}

图15-18 SummaryReport.java

(第10——第22个问题省略。)

本文摘自《全栈性能测试修炼宝典》

图片描述

全栈性能测试修炼宝典,JMeter实战一本专家撰写的、上万名学员实践过的、众多一线专拣推荐的、看得懂、学的全面的、帮助读者尽快精通软件性能测试图书。

图片描述

评论