专栏首页7DGroup性能工具之JMeter两个Java API Demo

性能工具之JMeter两个Java API Demo

概述

本文演示两个通过Java API执行JMeter脚本的示例

主要功能

  • 在线生成jmx脚本(demo1)
  • 加载本地已有 jmx 脚本(demo2)
  • 运行多个 Sampler
  • 将生成的 TestPlan 存储为. jmx 文件
  • 执行单机压测
  • 将测试执行结果存储为 .jtl or .csv 文件

示例

Maven配置

为了开始使用 JMeter API,我们首先需要将它添加到我们的 pom.xml

<dependencies>
        <dependency>
            <groupId>org.apache.jmeter</groupId>
            <artifactId>ApacheJMeter_java</artifactId>
            <version>4.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.jmeter</groupId>
            <artifactId>ApacheJMeter_http</artifactId>
            <version>4.0</version>
        </dependency>
    </dependencies>

在线生成jmx脚本(demo1)

/**
 * 代码生成测试脚本,及JMX文件Demo
 * 1)先定义每个组件的生成方式,然后再按一定结构组装各个组件,最后生成JMX文件
 * 2)生成.jtl结果文件
 * 2)单机压测
 */

public class JMeterDemo1 {

    public static void main(String[] argv) throws Exception {

        // 设置jmeterHome路径
        // 主要是读取了几个配置文件,jmeter.properties,user.properties,system.properties。
        // 设置一下的本地的Locale环境。
        // 其实到这里,是可以仅将这3个配置文件抽离出来,即不需要整个Jmeter的home目录,仅要这3个配置文件就能运行Jmeter脚本。
        // 甚至仅在代码中写要的配置,都不需要实体的配置文件即可。
        // 当然随着功能越来越多,平台跟Jmeter的耦合也越来越多,这个Jmeter_home目录还是越来越必要了。
        String jmeterHome1 = "/Users/apple/Downloads/performance/apache-jmeter-4.0";
        //File jmeterHome = new File(System.getProperty("jmeter.home"));
        File jmeterHome = new File(jmeterHome1);
        // 分隔符
        String slash = System.getProperty("file.separator");

        //判断jmeterHome
        if (jmeterHome.exists()) {
            File jmeterProperties = new File(jmeterHome.getPath() + slash + "bin" + slash + "jmeter.properties");
            if (jmeterProperties.exists()) {

                // 初始化压测引擎
                StandardJMeterEngine jmeter = new StandardJMeterEngine();

                // JMeter初始化(属性、日志级别、区域设置等)
                JMeterUtils.setJMeterHome(jmeterHome.getPath());
                JMeterUtils.loadJMeterProperties(jmeterProperties.getPath());
                // 可以注释这一行,查看额外的日志,例如DEBUG级别
                JMeterUtils.initLogging();
                JMeterUtils.initLocale();

                // JMeter测试计划,基本上是JOrphan HashTree
                HashTree testPlanTree = new HashTree();

                // 第一个 HTTP Sampler - 打开 baidu.com
                HTTPSamplerProxy baiducomSampler = new HTTPSamplerProxy();
                baiducomSampler.setDomain("baidu.com");
                baiducomSampler.setPort(80);
                baiducomSampler.setPath("/");
                baiducomSampler.setMethod("GET");
                baiducomSampler.setName("Open baidu.com");
                baiducomSampler.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
                baiducomSampler.setProperty(TestElement.GUI_CLASS, HttpTestSampleGui.class.getName());

                // 第二个 HTTP Sampler - 打开 qq.com
                HTTPSamplerProxy qqcomSampler = new HTTPSamplerProxy();
                qqcomSampler.setDomain("qq.com");
                qqcomSampler.setPort(80);
                qqcomSampler.setPath("/");
                qqcomSampler.setMethod("GET");
                qqcomSampler.setName("Open qq.com");
                qqcomSampler.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
                qqcomSampler.setProperty(TestElement.GUI_CLASS, HttpTestSampleGui.class.getName());

                // Loop Controller 循环控制
                LoopController loopController = new LoopController();
                loopController.setLoops(1);
                loopController.setFirst(true);
                loopController.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
                loopController.setProperty(TestElement.GUI_CLASS, LoopControlPanel.class.getName());
                loopController.initialize();

                // Thread Group 线程组
                ThreadGroup threadGroup = new ThreadGroup();
                threadGroup.setName("Example Thread Group");
                threadGroup.setNumThreads(1);
                threadGroup.setRampUp(1);
                threadGroup.setSamplerController(loopController);
                threadGroup.setProperty(TestElement.TEST_CLASS, ThreadGroup.class.getName());
                threadGroup.setProperty(TestElement.GUI_CLASS, ThreadGroupGui.class.getName());

                // Test Plan 测试计划
                TestPlan testPlan = new TestPlan("创建JMeter脚本");
                testPlan.setProperty(TestElement.TEST_CLASS, TestPlan.class.getName());
                testPlan.setProperty(TestElement.GUI_CLASS, TestPlanGui.class.getName());
                testPlan.setUserDefinedVariables((Arguments) new ArgumentsPanel().createTestElement());

                // 从以上初始化的元素构造测试计划
                testPlanTree.add(testPlan);
                HashTree threadGroupHashTree = testPlanTree.add(testPlan, threadGroup);
                threadGroupHashTree.add(baiducomSampler);
                threadGroupHashTree.add(qqcomSampler);

                // 将生成的测试计划保存为JMeter的.jmx文件格式
                SaveService.saveTree(testPlanTree, new FileOutputStream(jmeterHome + slash + "example.jmx"));

                // 在stdout中添加summary输出,得到测试进度,如:
                // summary =      2 in   1.3s =    1.5/s Avg:   631 Min:   290 Max:   973 Err:     0 (0.00%)
                Summariser summer = null;
                String summariserName = JMeterUtils.getPropDefault("summariser.name", "summary");
                if (summariserName.length() > 0) {
                    summer = new Summariser(summariserName);
                }

                // 将执行结果存储到.jtl文件中
                String logFile = jmeterHome + slash + "example.jtl";
                ResultCollector logger = new ResultCollector(summer);
                logger.setFilename(logFile);
                testPlanTree.add(testPlanTree.getArray()[0], logger);


                // 单机执行测试计划
                jmeter.configure(testPlanTree);  // 设置回调监听器,并添加状态
                jmeter.run();

                System.out.println("生成结果文件:" + jmeterHome + slash + "example.jtl");
                System.out.println("Jmx脚本文件:" + jmeterHome + slash + "example.jmx");
                System.exit(0);
            }
        }

        System.err.println("jmeter.home 未设置或指向不正确的位置");
        System.exit(1);
    }
}

运行结果:

summary +      1 in 00:00:04 =    0.2/s Avg:  1728 Min:  1728 Max:  1728 Err:     0 (0.00%) Active: 1 Started: 1 Finished: 0
summary +      1 in 00:00:01 =    1.9/s Avg:   514 Min:   514 Max:   514 Err:     0 (0.00%) Active: 0 Started: 1 Finished: 1
summary =      2 in 00:00:05 =    0.4/s Avg:  1121 Min:   514 Max:  1728 Err:     0 (0.00%)
生成结果文件:/Users/apple/Downloads/performance/apache-jmeter-4.0/example.jtl
Jmx脚本文件:/Users/apple/Downloads/performance/apache-jmeter-4.0/example.jmx

Process finished with exit code 0

加载本地jmx脚本(demo2)

/**
 * 上传现成脚本demo
 * 1)加载本地JMX文件并解析
 * 2)生成.csv格式结果
 * * */

public class JMeterDemo2 {

    public static void main(String[] argv) throws Exception {
        // 设置jmeterHome路径
        String jmeterHome1 = "/Users/apple/Downloads/performance/apache-jmeter-4.0";
        //File jmeterHome = new File(System.getProperty("jmeter.home"));
        File jmeterHome = new File(jmeterHome1);
        File jmxFile = new File(jmeterHome1 + "/example.jmx");

        // 分隔符
        String slash = System.getProperty("file.separator");

        // 判断jmeterHome
        if (jmeterHome.exists()) {
            File jmeterProperties = new File(jmeterHome.getPath() + slash + "bin" + slash + "jmeter.properties");
            if (jmeterProperties.exists()) {

                // 初始化压测引擎
                StandardJMeterEngine jmeter = new StandardJMeterEngine();

                // JMeter初始化(属性、日志级别、区域设置等)
                JMeterUtils.setJMeterHome(jmeterHome.getPath());
                JMeterUtils.loadJMeterProperties(jmeterProperties.getPath());
                // 可以注释这一行,查看额外的日志,例如DEBUG级别
                JMeterUtils.initLogging();
                JMeterUtils.initLocale();

                // JMeter测试计划,基本上是JOrphan HashTree
                HashTree testPlanTree = new HashTree();

                // 设置jmx脚本文件的工作目录,可以根据这个来找到参数化文件及实现其文件流。
                FileServer.getFileServer().setBaseForScript(jmxFile);

                // 加载jmx脚本,本身这个操作非常复杂。
                // jmx脚本中通常会包含参数化文件,用户自定义的参数化,Jmeter自定义函数,各种Sampler的实现,断言,甚至用户自定义的插件等等。
                // 同时还有各种监听接口的初始化。
                // 这些都是要找到实现类加载的,源码中包含非常多的实现类。
                testPlanTree = SaveService.loadTree(jmxFile);

                // 去掉没用的节点元素,替换掉可以替换的控制器,这个是递归实现的,比较复杂
                JMeter.convertSubTree(testPlanTree);

                // 在stdout中添加summary输出,得到测试进度,如:
                // summary =      2 in   1.3s =    1.5/s Avg:   631 Min:   290 Max:   973 Err:     0 (0.00%)
                Summariser summer = null;
                String summariserName = JMeterUtils.getPropDefault("summariser.name", "summary");
                if (summariserName.length() > 0) {
                    summer = new Summariser(summariserName);
                }

                // 将执行结果存储到.csv文件中
                String logFile = jmeterHome + slash + "example.csv";
                ResultCollector logger = new ResultCollector(summer);
                logger.setFilename(logFile);
                testPlanTree.add(testPlanTree.getArray()[0], logger);

                // 单机执行测试计划
                jmeter.configure(testPlanTree);  // 设置回调监听器,并添加状态
                jmeter.run();

                System.out.println("生成结果文件:" + jmeterHome + slash + "example.csv");
                System.out.println("加载Jmx脚本文件:" + jmeterHome + slash + "example.jmx");
                System.exit(0);
            }
        }
        System.err.println("jmeter.home 未设置或指向不正确的位置");
        System.exit(1);
    }
}

运行结果:

summary +      1 in 00:00:04 =    0.3/s Avg:  1426 Min:  1426 Max:  1426 Err:     0 (0.00%) Active: 1 Started: 1 Finished: 0
summary +      1 in 00:00:00 =    3.0/s Avg:   281 Min:   281 Max:   281 Err:     0 (0.00%) Active: 0 Started: 1 Finished: 1
summary =      2 in 00:00:04 =    0.5/s Avg:   853 Min:   281 Max:  1426 Err:     0 (0.00%)
生成结果文件:/Users/apple/Downloads/performance/apache-jmeter-4.0/example.csv
加载Jmx脚本文件:/Users/apple/Downloads/performance/apache-jmeter-4.0/example.jmx

本文源码:

https://github.com/7DGroup/JMeter-API-Demo

本文分享自微信公众号 - 7DGroup(Zee_7DGroup)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-02-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 微信小程序开发基础

    查看官方文档:https://developers.weixin.qq.com/miniprogram/dev/component/

    达达前端
  • XGBoost类库使用小结

        在XGBoost算法原理小结中,我们讨论了XGBoost的算法原理,这一片我们讨论如何使用XGBoost的Python类库,以及一些重要参数的意义和调参...

    刘建平Pinard
  • JavaScript学习之路-为什么要学习JavaScript语法

    为什么要学习JavaScript语法,没有理由,因为工作需要,也为了成为全栈,那现在还是好好努力学习吧!

    达达前端
  • Android网络请求与数据解析,使用Gson和GsonFormat解析复杂Json数据

    【达叔有道】软件技术人员,时代作者,从 Android 到全栈之路,我相信你也可以!阅读他的文章,会上瘾!You and me, we are family !

    达达前端
  • 深度学习框架对决篇:Keras VS PyTorch

    TensorFlow 是很多科学家、工程师和开发人员的首个深度学习框架。虽然 TensorFlow 1.0 早在 2017 年 2 月就发布了,但使用过程中对用...

    小小詹同学
  • 「决战紫禁之巅」之深度学习框架篇:Keras VS PyTorch

    TensorFlow 是很多科学家、工程师和开发人员的首个深度学习框架。虽然 TensorFlow 1.0 早在 2017 年 2 月就发布了,但使用过程中对用...

    机器之心
  • 车辆违章查询和限行提醒程序 -- (1) 限行提醒功能的实现和接入短信接口

    闲来无事,想做一个小网站,方便查询车辆违章信息,后来一想直接写个程序,每天定时查询违章信息,有了违章则发短信和邮件提醒用户,还可以自定义限行策略,在限号那天提醒...

    浩Coding
  • 第二十节:详细讲解String和StringBuffer和StringBuilder的使用

    在 Java中的字符串属于对象,那么Java 中提供了 String 类来创建和操作字符串,即是使用对象;因为String类修饰的字符一旦被创建就不可改变,所以...

    达达前端
  • 微信小程序基础

    查看官方文档:https://developers.weixin.qq.com/miniprogram/dev/component/

    达达前端
  • 基于tensorflow的图像处理(二) tf.image的使用方法

    对图像进行预处理,可以尽量避免模型受到无关因素的影响。大部分图像识别问题中,通过图像预处理过程可以提高模型的准确率。

    于小勇

扫码关注云+社区

领取腾讯云代金券