首页 > 编程语言 >性能工具之JMeter两个Java API Demo

性能工具之JMeter两个Java API Demo

时间:2023-04-03 14:32:19浏览次数:59  
标签:jmx Java Demo System API File new jmeter jmeterHome

性能工具之JMeter两个Java API Demo_System

概述

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

主要功能

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

示例

Maven配置

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


1. <dependencies>
2.         <dependency>
3.             <groupId>org.apache.jmeter</groupId>
4.             <artifactId>ApacheJMeter_java</artifactId>
5.             <version>4.0</version>
6.         </dependency>
7.         <dependency>
8.             <groupId>org.apache.jmeter</groupId>
9.             <artifactId>ApacheJMeter_http</artifactId>
10.             <version>4.0</version>
11.         </dependency>
12.     </dependencies>

在线生成jmx脚本(demo1)


1. /**
2.  * 代码生成测试脚本,及JMX文件Demo
3.  * 1)先定义每个组件的生成方式,然后再按一定结构组装各个组件,最后生成JMX文件
4.  * 2)生成.jtl结果文件
5.  * 2)单机压测
6.  */
7. 
8. public class JMeterDemo1 {
9. 
10.     public static void main(String[] argv) throws Exception {
11. 
12.         // 设置jmeterHome路径
13.         // 主要是读取了几个配置文件,jmeter.properties,user.properties,system.properties。
14.         // 设置一下的本地的Locale环境。
15.         // 其实到这里,是可以仅将这3个配置文件抽离出来,即不需要整个Jmeter的home目录,仅要这3个配置文件就能运行Jmeter脚本。
16.         // 甚至仅在代码中写要的配置,都不需要实体的配置文件即可。
17.         // 当然随着功能越来越多,平台跟Jmeter的耦合也越来越多,这个Jmeter_home目录还是越来越必要了。
18.         String jmeterHome1 = "/Users/apple/Downloads/performance/apache-jmeter-4.0";
19.         //File jmeterHome = new File(System.getProperty("jmeter.home"));
20.         File jmeterHome = new File(jmeterHome1);
21.         // 分隔符
22.         String slash = System.getProperty("file.separator");
23. 
24.         //判断jmeterHome
25.         if (jmeterHome.exists()) {
26.             File jmeterProperties = new File(jmeterHome.getPath() + slash + "bin" + slash + "jmeter.properties");
27.             if (jmeterProperties.exists()) {
28. 
29.                 // 初始化压测引擎
30.                 StandardJMeterEngine jmeter = new StandardJMeterEngine();
31. 
32.                 // JMeter初始化(属性、日志级别、区域设置等)
33.                 JMeterUtils.setJMeterHome(jmeterHome.getPath());
34.                 JMeterUtils.loadJMeterProperties(jmeterProperties.getPath());
35.                 // 可以注释这一行,查看额外的日志,例如DEBUG级别
36.                 JMeterUtils.initLogging();
37.                 JMeterUtils.initLocale();
38. 
39.                 // JMeter测试计划,基本上是JOrphan HashTree
40.                 HashTree testPlanTree = new HashTree();
41. 
42.                 // 第一个 HTTP Sampler - 打开 baidu.com
43.                 HTTPSamplerProxy baiducomSampler = new HTTPSamplerProxy();
44.                 baiducomSampler.setDomain("baidu.com");
45.                 baiducomSampler.setPort(80);
46.                 baiducomSampler.setPath("/");
47.                 baiducomSampler.setMethod("GET");
48.                 baiducomSampler.setName("Open baidu.com");
49.                 baiducomSampler.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
50.                 baiducomSampler.setProperty(TestElement.GUI_CLASS, HttpTestSampleGui.class.getName());
51. 
52.                 // 第二个 HTTP Sampler - 打开 qq.com
53.                 HTTPSamplerProxy qqcomSampler = new HTTPSamplerProxy();
54.                 qqcomSampler.setDomain("qq.com");
55.                 qqcomSampler.setPort(80);
56.                 qqcomSampler.setPath("/");
57.                 qqcomSampler.setMethod("GET");
58.                 qqcomSampler.setName("Open qq.com");
59.                 qqcomSampler.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
60.                 qqcomSampler.setProperty(TestElement.GUI_CLASS, HttpTestSampleGui.class.getName());
61. 
62.                 // Loop Controller 循环控制
63.                 LoopController loopController = new LoopController();
64.                 loopController.setLoops(1);
65.                 loopController.setFirst(true);
66.                 loopController.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
67.                 loopController.setProperty(TestElement.GUI_CLASS, LoopControlPanel.class.getName());
68.                 loopController.initialize();
69. 
70.                 // Thread Group 线程组
71.                 ThreadGroup threadGroup = new ThreadGroup();
72.                 threadGroup.setName("Example Thread Group");
73.                 threadGroup.setNumThreads(1);
74.                 threadGroup.setRampUp(1);
75.                 threadGroup.setSamplerController(loopController);
76.                 threadGroup.setProperty(TestElement.TEST_CLASS, ThreadGroup.class.getName());
77.                 threadGroup.setProperty(TestElement.GUI_CLASS, ThreadGroupGui.class.getName());
78. 
79.                 // Test Plan 测试计划
80.                 TestPlan testPlan = new TestPlan("创建JMeter脚本");
81.                 testPlan.setProperty(TestElement.TEST_CLASS, TestPlan.class.getName());
82.                 testPlan.setProperty(TestElement.GUI_CLASS, TestPlanGui.class.getName());
83.                 testPlan.setUserDefinedVariables((Arguments) new ArgumentsPanel().createTestElement());
84. 
85.                 // 从以上初始化的元素构造测试计划
86.                 testPlanTree.add(testPlan);
87.                 HashTree threadGroupHashTree = testPlanTree.add(testPlan, threadGroup);
88.                 threadGroupHashTree.add(baiducomSampler);
89.                 threadGroupHashTree.add(qqcomSampler);
90. 
91.                 // 将生成的测试计划保存为JMeter的.jmx文件格式
92.                 SaveService.saveTree(testPlanTree, new FileOutputStream(jmeterHome + slash + "example.jmx"));
93. 
94.                 // 在stdout中添加summary输出,得到测试进度,如:
95.                 // summary =      2 in   1.3s =    1.5/s Avg:   631 Min:   290 Max:   973 Err:     0 (0.00%)
96.                 Summariser summer = null;
97.                 String summariserName = JMeterUtils.getPropDefault("summariser.name", "summary");
98.                 if (summariserName.length() > 0) {
99.                     summer = new Summariser(summariserName);
100.                 }
101. 
102.                 // 将执行结果存储到.jtl文件中
103.                 String logFile = jmeterHome + slash + "example.jtl";
104.                 ResultCollector logger = new ResultCollector(summer);
105.                 logger.setFilename(logFile);
106.                 testPlanTree.add(testPlanTree.getArray()[0], logger);
107. 
108. 
109.                 // 单机执行测试计划
110.                 jmeter.configure(testPlanTree);  // 设置回调监听器,并添加状态
111.                 jmeter.run();
112. 
113.                 System.out.println("生成结果文件:" + jmeterHome + slash + "example.jtl");
114.                 System.out.println("Jmx脚本文件:" + jmeterHome + slash + "example.jmx");
115.                 System.exit(0);
116.             }
117.         }
118. 
119.         System.err.println("jmeter.home 未设置或指向不正确的位置");
120.         System.exit(1);
121.     }
122. }

运行结果:


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
2. 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
3. summary =      2 in 00:00:05 =    0.4/s Avg:  1121 Min:   514 Max:  1728 Err:     0 (0.00%)
4. 生成结果文件:/Users/apple/Downloads/performance/apache-jmeter-4.0/example.jtl
5. Jmx脚本文件:/Users/apple/Downloads/performance/apache-jmeter-4.0/example.jmx
6. 
7. Process finished with exit code 0

加载本地jmx脚本(demo2)

1. /**
2.  * 上传现成脚本demo
3.  * 1)加载本地JMX文件并解析
4.  * 2)生成.csv格式结果
5.  * * */
6. 
7. public class JMeterDemo2 {
8. 
9.     public static void main(String[] argv) throws Exception {
10.         // 设置jmeterHome路径
11.         String jmeterHome1 = "/Users/apple/Downloads/performance/apache-jmeter-4.0";
12.         //File jmeterHome = new File(System.getProperty("jmeter.home"));
13.         File jmeterHome = new File(jmeterHome1);
14.         File jmxFile = new File(jmeterHome1 + "/example.jmx");
15. 
16.         // 分隔符
17.         String slash = System.getProperty("file.separator");
18. 
19.         // 判断jmeterHome
20.         if (jmeterHome.exists()) {
21.             File jmeterProperties = new File(jmeterHome.getPath() + slash + "bin" + slash + "jmeter.properties");
22.             if (jmeterProperties.exists()) {
23. 
24.                 // 初始化压测引擎
25.                 StandardJMeterEngine jmeter = new StandardJMeterEngine();
26. 
27.                 // JMeter初始化(属性、日志级别、区域设置等)
28.                 JMeterUtils.setJMeterHome(jmeterHome.getPath());
29.                 JMeterUtils.loadJMeterProperties(jmeterProperties.getPath());
30.                 // 可以注释这一行,查看额外的日志,例如DEBUG级别
31.                 JMeterUtils.initLogging();
32.                 JMeterUtils.initLocale();
33. 
34.                 // JMeter测试计划,基本上是JOrphan HashTree
35.                 HashTree testPlanTree = new HashTree();
36. 
37.                 // 设置jmx脚本文件的工作目录,可以根据这个来找到参数化文件及实现其文件流。
38.                 FileServer.getFileServer().setBaseForScript(jmxFile);
39. 
40.                 // 加载jmx脚本,本身这个操作非常复杂。
41.                 // jmx脚本中通常会包含参数化文件,用户自定义的参数化,Jmeter自定义函数,各种Sampler的实现,断言,甚至用户自定义的插件等等。
42.                 // 同时还有各种监听接口的初始化。
43.                 // 这些都是要找到实现类加载的,源码中包含非常多的实现类。
44.                 testPlanTree = SaveService.loadTree(jmxFile);
45. 
46.                 // 去掉没用的节点元素,替换掉可以替换的控制器,这个是递归实现的,比较复杂
47.                 JMeter.convertSubTree(testPlanTree);
48. 
49.                 // 在stdout中添加summary输出,得到测试进度,如:
50.                 // summary =      2 in   1.3s =    1.5/s Avg:   631 Min:   290 Max:   973 Err:     0 (0.00%)
51.                 Summariser summer = null;
52.                 String summariserName = JMeterUtils.getPropDefault("summariser.name", "summary");
53.                 if (summariserName.length() > 0) {
54.                     summer = new Summariser(summariserName);
55.                 }
56. 
57.                 // 将执行结果存储到.csv文件中
58.                 String logFile = jmeterHome + slash + "example.csv";
59.                 ResultCollector logger = new ResultCollector(summer);
60.                 logger.setFilename(logFile);
61.                 testPlanTree.add(testPlanTree.getArray()[0], logger);
62. 
63.                 // 单机执行测试计划
64.                 jmeter.configure(testPlanTree);  // 设置回调监听器,并添加状态
65.                 jmeter.run();
66. 
67.                 System.out.println("生成结果文件:" + jmeterHome + slash + "example.csv");
68.                 System.out.println("加载Jmx脚本文件:" + jmeterHome + slash + "example.jmx");
69.                 System.exit(0);
70.             }
71.         }
72.         System.err.println("jmeter.home 未设置或指向不正确的位置");
73.         System.exit(1);
74.     }
75. }

运行结果:

    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
    2. 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
    3. summary =      2 in 00:00:04 =    0.5/s Avg:   853 Min:   281 Max:  1426 Err:     0 (0.00%)
    4. 生成结果文件:/Users/apple/Downloads/performance/apache-jmeter-4.0/example.csv
    5. 加载Jmx脚本文件:/Users/apple/Downloads/performance/apache-jmeter-4.0/example.jmx


    本文源码:

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

    标签:jmx,Java,Demo,System,API,File,new,jmeter,jmeterHome
    From: https://blog.51cto.com/u_15181572/6166357

    相关文章

    • java稀疏数组实现实例
      没有原理讲解,仅记录一个实现代码,作为参考和笔记使用如题,稀疏数组仅在原始数组有效数据较少的情况下起压缩空间的作用实现过程:首先为了方便查看和确认,封装一个打印二维数组的方法publicstaticvoidprintArray(int[][]arrays){for(int[]array:arrays){......
    • 利用高德地图 API 显示地图信息
      ​摘要 这次,我们使用高德地图的Web端(JSAPI),在免费的paas平台应用上通过输入的地址来自动生成地图。用到的高德地图服务API地图显示和标注地理编码(获取经纬度)※此例仅作开发参考,一切商用目的或者其他许可请参考高德相关网站条例。 完成图像在这篇技巧文章中,我们使......
    • 114.二叉树展开为链表 Java
      114.二叉树展开为链表给你二叉树的根结点root,请你将它展开为一个单链表:展开后的单链表应该同样使用TreeNode,其中right子指针指向链表中下一个结点,而左子指针始终为null。展开后的单链表应该与二叉树先序遍历顺序相同。示例1:输入:root=[1,2,5,3,4,null,6]输出......
    • 详细解析Java异步线程处理队列任务工具类以及实战
      场景待入快速理解小场景描述:【一群人】来到【一个大厅】办理业务,大厅中有【多个窗口】给我们办理业务。每个人都有自己要办事情,处理过程需要消耗时间。大厅根据人群多少,开始窗口梳理。如果把“一群人”理解成一群待处理的n个【任务】,把这群人排成一个长队就形成了一个【任......
    • 【】Java Error: Port 9095 was already in use
      问题描述JavaError:Port9095wasalreadyinuse问题原因端口被占用导致解决方案Windsow系统netstat-ano|findstr9090查询到占用9090端口的进程PID为9784。tasklist|findstr9784查询到PID为0=7984的进程打开【任务管理器】->【服务】,将对应应用关闭Lin......
    • Java 缺失的特性:扩展方法
      作者:周密(之叶)什么是扩展方法扩展方法,就是能够向现有类型直接“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改现有类型。调用扩展方法的时候,与调用在类型中实际定义的方法相比没有明显的差异。为什么需要扩展方法考虑要实现这样的功能:从Redis取出包含多个商......
    • Java 缺失的特性:扩展方法
      作者:周密(之叶)什么是扩展方法扩展方法,就是能够向现有类型直接“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改现有类型。调用扩展方法的时候,与调用在类型中实际定义的方法相比没有明显的差异。为什么需要扩展方法考虑要实现这样的功能:从Redis取出包含多个商品ID......
    • java vue获取当月第一天和最后一天,当前周一和周日
      1,vue前端,通过moment获取当月第一天和最后一天,当前周一和周日letcurrDate=moment(newDate(),"YYYY-MM-DD");varfirstDay=moment(currDate.startOf("month").valueOf()).format('YYYY-MM-DD');//获取该月份第一天的时间戳varendDay=moment(cur......
    • Java-Day-1(Java了解 + DOS)
      Java-Day-1JAVA分辨了解Java创始人之一:詹姆斯·高斯林解释性语言,编译出.class后是有一个解释器的(编译性语言:C/C++——编译后的代码已经是二进制可以由机器直接执行了)面向对象的(oop)健壮的跨平台性的一个.java编译好的.class文件,无需再次编译,便既能在windows上......
    • Java-Day-2(转义字符 + 注释 + 代码规范 + 变量 + 数据类型)
      Java-Day-2常用转义字符代码中只一个\会默认转义(写在“”里)\t:制表位,可以实现对齐功能,可以看作有一个无形表框(上下两行长度相差不大)\n:换行符,仅换代码行的话\\:一个\,想输出"\\"就要输入四个\\'':一个“,字符串里输出双引号\':一个‘\r:一个回车,光标......