jmeter中java协议请求

测试工具:myecplise10.5

jdk版本:1.8.73

jmeter: 2.13

 

一、核心步骤

1.创建一个Java工程;

2.将JMeter的lib目录下的jar文件添加进此工程的Build Path;

3.创建一个类并实现JavaSamplerClient接口继承AbstractJavaSamplerClient,并重写;

public Arguments getDefaultParameters();设置可用参数及的默认值,已设置的参数会显示在jmeter GUI的参数列表中;
public void setupTest(JavaSamplerContext arg0):每个线程测试前执行一次,做一些初始化工作;
public SampleResult runTest(JavaSamplerContext arg0):开始测试,从arg0参数可以获得参数值,并调用被测方法,完成与服务器的交互;
public void teardownTest(JavaSamplerContext arg0):测试结束时调用;

  setupTest和teardownTest方法不需要时可以不写。runTest 该方法是java Sampler实现的重点,执行次数取决于线程数和循环次数。

  以上4个方法中只有runTest是必须实现的,其他3个可根据需求去覆盖。这4个方法执行的先后顺序与其前面的显示顺序相对应。

  如果需要对多个方法进行性能测试,则需要建多个测试类,多个测试类可以放在同一个包下面,也可以放在单独的包中。

4.Export为Runnable Jar File

5.将此jar包放入JMETER_HOME\lib\ext目录;

6.以管理员身份打开JMeter;

7.创建线程组、Java Request、查看结果树,进行测试;

 

二、实例

1.在eclipse里面新建一个工程:JavaForJMeter

2.把{Jmeter_home}\lib目录下的所有jar,引用的jar包复制到lib目录,并添加进此工程的Build Path;

注意:lib\ext目录下ApacheJMeter_core.jar,ApacheJMeter_java.jar两个jar包肯定需要build到项目中,另外还需要对其如果在ecplise中执行时报其他错可再添加相应的jar包。为方便,就可导入lib目录下的所有jar包。 

  Logkit-2.0.jar :记录 jmeter 打屏日志使用的包
  Httpclient-4.3.2.jar : http 相关接口包

 

3.添加类Hello,代码如下:

jmeter中java协议请求
package test;

public class Hello {
    public String sayHello()
    {
        return "Hello";
    }
//    public String sayHelloToPerson(String s)
//    {
//        if(s == null || s.equals(""))
//            s = "nobody";
//        return (new StringBuilder()).append("Hello ").append(s).toString();
//    }
    public int sum(int a,int b)
    {
        return a+b;
    }
}
jmeter中java协议请求

4.添加类perftest,并继承AbstractJavaSamplerClient,并添加代码如下:

注意:

1)System.out等的输出会显示在启动JMeter时的命令窗口内,但过多的输出会影响性能的准确性。

2)http请求在任何情况下都会有给客户端一个反馈,但是java请求不一定。在设置的压力较大时,服务器可能会吃不消直接异常退出,客户端获取不到任何返回值,保存返回结果的对象(如本例中的resultData)的值就为null。所以需要做空指针的判断,保证代码的正常运行。

jmeter中java协议请求
package test;

import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;
import test.Hello;

public class test extends AbstractJavaSamplerClient {
    private String a;
    private String b;

    private String resultData = null ;

    // 这个方法是用来自定义java方法入参的。
    // params.addArgument("num1","");表示入参名字叫num1,默认值为空。
    // 设置可用参数及的默认值;
    public Arguments getDefaultParameters() {
        Arguments params = new Arguments();
        params.addArgument("num1", "");//未设默认值
        params.addArgument("num2", "");
        return params;
    }

    // 每个线程测试前执行一次,做一些初始化工作;
    public void setupTest(JavaSamplerContext arg0) {
  
    }

    // 开始测试,从arg0参数可以获得参数值;
    public SampleResult runTest(JavaSamplerContext arg0) {
            a = arg0.getParameter("num1");
            b = arg0.getParameter("num2");
            SampleResult sr = new SampleResult();
            sr.setSampleLabel("qingqiu");

            try {
                sr.sampleStart();// jmeter 开始统计响应时间标记
                Hello test = new Hello();
                // 通过下面的操作就可以将被测方法的响应输出到Jmeter的察看结果树中的响应数据里面了。
                resultData = String.valueOf(test.sum(Integer.parseInt(a), Integer
                        .parseInt(b)));
                if (resultData != null && resultData.length() > 0) {
                    sr.setResponseData("结果是:"+resultData, null);//第二个参数指定编码方法
                    sr.setDataType(SampleResult.TEXT);
                }
                System.out.println(resultData);
                sr.setSuccessful(true); //将这行放在上边if语句里更好?
            } catch (Throwable e) {
                sr.setSuccessful(false); //设置本次测试结果为false
                e.printStackTrace();
            } finally {
                sr.sampleEnd();// jmeter 结束统计响应时间标记
            }
            return sr;
        }

    // 测试结束时调用;
    public void teardownTest(JavaSamplerContext arg0) {
         //System.out.println(end);
        // System.out.println("The cost is"+(end-start)/1000);
    }

    // main只是为了调试用,最后打jar包的时候注释掉。

      public static void main(String[] args) { 
          Arguments params = new Arguments(); 
          params.addArgument("num1", "1");//设置参数,并赋予默认值1 
          params.addArgument("num2", "2");//设置参数,并赋予默认值2
          JavaSamplerContext arg0 = new JavaSamplerContext(params); 
          test test = new test(); 
          test.setupTest(arg0); //无初始化,可不使用
          test.runTest(arg0);
          test.teardownTest(arg0); //方法中无代码,可不使用
      }


}
jmeter中java协议请求

main方法执行结果如下: 

jmeter中java协议请求
WARN    2016-03-20 00:20:01.895 [jmeter.u] (): Unexpected value set for boolean property:'sampleresult.getbytes.body_real_size', defaulting to:true
WARN    2016-03-20 00:20:01.941 [jmeter.u] (): Unexpected value set for boolean property:'sampleresult.getbytes.headers_size', defaulting to:true
WARN    2016-03-20 00:20:01.941 [jmeter.u] (): Unexpected value set for boolean property:'sampleresult.timestamp.start', defaulting to:false
WARN    2016-03-20 00:20:01.941 [jmeter.u] (): Unexpected value set for boolean property:'sampleresult.useNanoTime', defaulting to:true
WARN    2016-03-20 00:20:01.941 [jmeter.u] (): Unexpected value set for int property:'sampleresult.nanoThreadSleep', defaulting to:5000
INFO    2016-03-20 00:20:01.941 [jmeter.s] (): Note: Sample TimeStamps are END times
INFO    2016-03-20 00:20:01.942 [jmeter.s] (): sampleresult.default.encoding is set to ISO-8859-1
INFO    2016-03-20 00:20:01.942 [jmeter.s] (): sampleresult.useNanoTime=true
INFO    2016-03-20 00:20:01.942 [jmeter.s] (): sampleresult.nanoThreadSleep=5000
3
jmeter中java协议请求

 

5.Export为Runnable Jar File:hello.jar

注意:不需要将整个工程导出,只需要选中包名(test)在file菜单中点击export-》选java项的jar file-》默认选项,设置jar路径,生成相应可以执行jar包。

 

修改MANIFEST.MF。MANIFEST.MF文件描述了jar包的相关信息,包括jar包的版本、创建人和类搜索路径等。如果是可执行jar包,会包含Main-Class属性,表明Main方法入口。Class-Path指定依赖的jar包,当前路径是jar包所在目录,若要引用当前目录下一个子目录中的jar包,使用以下格式:子目录/jar包名称,多个jar包之间用空格分隔,在任何平台上路径分割符都是'/'。

 

如果导出的jar包依赖了别的jar包,需要在MANIFEST.MF文件中指明依赖的jar包的名字。在导出的jar包上右键,选择用WinRAR打开,打开META_INF\MANIFEST.MF文件,添加依赖的jar包的名字,名字之前用空格分隔,比如:

 

Class-Path: lib/ApacheJMeter_core.jar lib/ApacheJMeter_java.jar lib/avalon-framework-4.1.4.jar lib/commons-logging-1.2.jar lib/logkit-2.0.jar

 

 

 

6.将此hello.jar包放入JMETER_HOME\lib\ext目录;

7.打开JMeter,添加线程组,添加Java请求,查看结果树。

在Thread Group上是右击,Add-->Sampler-->Java Request。

注意:此处java请求为sampler中的java请求,而非配置元件中的java请求默认值。只有添加的sampler中的java请求, 在查看结果树中才会有值。

在两个路径下的请求,都会生成如下日志:

jmeter中java协议请求
2016/03/20 00:27:33 INFO  - jmeter.engine.StandardJMeterEngine: Running the test! 
2016/03/20 00:27:33 INFO  - jmeter.samplers.SampleEvent: List of sample_variables: [] 
2016/03/20 00:27:33 INFO  - jmeter.gui.util.JMeterMenuBar: setRunning(true,*local*) 
2016/03/20 00:27:33 INFO  - jmeter.engine.StandardJMeterEngine: Starting ThreadGroup: 1 : 线程组 
2016/03/20 00:27:33 INFO  - jmeter.engine.StandardJMeterEngine: Starting 1 threads for group 线程组. 
2016/03/20 00:27:33 INFO  - jmeter.engine.StandardJMeterEngine: Thread will continue on error 
2016/03/20 00:27:33 INFO  - jmeter.threads.ThreadGroup: Starting thread group number 1 threads 1 ramp-up 1 perThread 1000.0 delayedStart=false 
2016/03/20 00:27:33 INFO  - jmeter.threads.ThreadGroup: Started thread group number 1 
2016/03/20 00:27:33 INFO  - jmeter.engine.StandardJMeterEngine: All thread groups have been started 
2016/03/20 00:27:33 INFO  - jmeter.threads.JMeterThread: Thread started: 线程组 1-1 
2016/03/20 00:27:33 INFO  - jmeter.threads.JMeterThread: Thread is done: 线程组 1-1 
2016/03/20 00:27:33 INFO  - jmeter.threads.JMeterThread: Thread finished: 线程组 1-1 
2016/03/20 00:27:33 INFO  - jmeter.engine.StandardJMeterEngine: Notifying test listeners of end of test 
2016/03/20 00:27:33 INFO  - jmeter.gui.util.JMeterMenuBar: setRunning(false,*local*) 
jmeter中java协议请求

 

jmeter中页面:

jmeter中java协议请求

 {Jmeter_home}\lib\ext目录下继承AbstractJavaSamplerClient类或实现JavaSamplerClient接口的测试类的类名都会出现在类名称后面的下拉框中,JaveTest和SleepTest为jmeter默认实现的2个java请求Sampler。

 参数化时,可使用CSV Data Set Config设置从文件中动态获取参数值,设置参数名称为num1,对应的值为${num1}。这里可直接使用固定值。

jmeter中java协议请求

一般不需要做统计分析的时候不用保存Response Data,并且如果要保存的Response Data数据量很大的话,可能会影响性能数据的准确性质。

如果要保存的话,还需要在configure(按钮在上面未显示出来),要同时勾选save as XML,save Response Data(XML)两项,并且需要指定结果数据要写入的文件名。不管指定的保存结果的文件格式是不是xml,结果数据都是以xml的格式存储的。

要注意的是,在服务器上执行jmeter的时候,也需要另外指定上面的保存结果信息的文件名及路径,因为Response Data是不会保存到-l参数后面指定的jtl文件中的。对其他信息的保存也可以参考这个方法。

选中请求后,可看到相应请求的“请求”与“响应数据”标签。

 

增加log日志:

jmeter中java协议请求
package test;

import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.log.Logger;

import test.Hello;

public class test extends AbstractJavaSamplerClient {
    private String a;
    private String b;
    
    private Logger log = getLogger(); // 在 jmeter 中 LogViewer 打印相关信息

    private String resultData;

    // 这个方法是用来自定义java方法入参的。
    // params.addArgument("num1","");表示入参名字叫num1,默认值为空。
    // 设置可用参数及的默认值;
    public Arguments getDefaultParameters() {
        log.info( "execute getDefaultParameters..." );
        Arguments params = new Arguments();
        params.addArgument("num1", "");
        params.addArgument("num2", "");
        return params;
    }

    // 每个线程测试前执行一次,做一些初始化工作;
    public void setupTest(JavaSamplerContext arg0) {
    }

    // 开始测试,从arg0参数可以获得参数值;
    public SampleResult runTest(JavaSamplerContext arg0) {
            log .info( "execute runTest..." );
            a = arg0.getParameter("num1");
            b = arg0.getParameter("num2");
            SampleResult sr = new SampleResult();
            sr.setSampleLabel("qingqiulog");
            try {
                sr.sampleStart();// jmeter 开始统计响应时间标记
                Hello test = new Hello();
                // 通过下面的操作就可以将被测方法的响应输出到Jmeter的察看结果树中的响应数据里面了。
                resultData = String.valueOf(test.sum(Integer.parseInt(a), Integer
                        .parseInt(b)));
                if (resultData != null && resultData.length() > 0) {
                    sr.setResponseData("结果是:"+resultData, null);
                    sr.setDataType(SampleResult.TEXT);
                }
                System.out.println(resultData);
                sr.setSuccessful(true);
                log.info( "sucess");
            } catch (Throwable e) {
                sr.setSuccessful(false);
                log.info( "fail..." );
                e.printStackTrace();
            } finally {
                sr.sampleEnd();// jmeter 结束统计响应时间标记
            }
            return sr;
        }

    // 测试结束时调用;
    public void teardownTest(JavaSamplerContext arg0) {
         log.info( "结束" );
         System.out.println("end");
        // System.out.println("The cost is"+(end-start)/1000);
    }

    // main只是为了调试用,最后打jar包的时候注释掉。

      public static void main(String[] args) { 
          Arguments params = new Arguments(); 
          params.addArgument("num1", "1");//设置参数,并赋予默认值1 
          params.addArgument("num2", "2");//设置参数,并赋予默认值2
          JavaSamplerContext arg0 = new JavaSamplerContext(params); 
          test test = new test(); 
          test.setupTest(arg0); 
          test.runTest(arg0);
          test.teardownTest(arg0); 
      }


}
jmeter中java协议请求

结果:

jmeter中java协议请求
INFO    2016-03-25 17:17:33.131 [jmeter.p] (): execute runTest...
WARN    2016-03-25 17:17:33.198 [jmeter.u] (): Unexpected value set for boolean property:'sampleresult.getbytes.body_real_size', defaulting to:true
WARN    2016-03-25 17:17:33.198 [jmeter.u] (): Unexpected value set for boolean property:'sampleresult.getbytes.headers_size', defaulting to:true
WARN    2016-03-25 17:17:33.199 [jmeter.u] (): Unexpected value set for boolean property:'sampleresult.timestamp.start', defaulting to:false
WARN    2016-03-25 17:17:33.199 [jmeter.u] (): Unexpected value set for boolean property:'sampleresult.useNanoTime', defaulting to:true
WARN    2016-03-25 17:17:33.199 [jmeter.u] (): Unexpected value set for int property:'sampleresult.nanoThreadSleep', defaulting to:5000
INFO    2016-03-25 17:17:33.199 [jmeter.s] (): Note: Sample TimeStamps are END times
INFO    2016-03-25 17:17:33.199 [jmeter.s] (): sampleresult.default.encoding is set to ISO-8859-1
INFO    2016-03-25 17:17:33.199 [jmeter.s] (): sampleresult.useNanoTime=true
INFO    2016-03-25 17:17:33.199 [jmeter.s] (): sampleresult.nanoThreadSleep=5000
3
INFO    2016-03-25 17:17:33.202 [jmeter.p] (): sucess
INFO    2016-03-25 17:17:33.202 [jmeter.p] (): 结束
end
jmeter中java协议请求

jmeter中java协议请求

 

 如果要出报告的话,需要添加“聚合报告”一项。

 

参考资料:

 http://www.cnblogs.com/zhangchaoyang/articles/2530731.html

Jmeter性能测试实践之java请求 具体实例写的比较细一些

http://blog.csdn.net/musen518/article/details/50327217

http://www.tuicool.com/articles/26ZV7n