JMeter下Groovy和BeanShell语言在不同组件中性能差异实践探究
一般而言JMeter下性能最好的是jar包这类java原生请求,对于JMeter并没有原生支持的请求,一般都会将其直接编译为jar包,然后再JMeter中调用,这样性能最好。
但是有些需求并不适合用jar包的方式来进行,比如报文拼接,这个一般在请求Sampler发送前执行,比较方便的是使用BeanShell或者Groovy等前置处理器操作。那对于这种报文拼接的操作,使用JSR233组件还是BeanShell组件,以及使用JSR233组件中的BeanShell还是Groovy之间有没有什么性能差异呢?
我们去翻了翻JMeter官方的相关介绍,只在JMeter官网的最佳实践“http://jmeter.apache.org/usermanual/best-practices.html”中找到对JSR233组件有如下的描述:
强烈建议在大压力测试场景中使用Groovy这个可以预编译的语言,而BeanShell虽然也实现了预编译的接口,但是却没有被编码进去。这段介绍并没有说JSR233组件和BeanShell组件之间的性能差异。
下面我们就写三个简单的脚本来看一下在前置处理器中Groovy和BeanShell两种语言以及JSR233组件和BeanShell组件的性能差异。脚本截图如下,文章最下面放上jxm原文件。
Groovy和BeanShell的前置处理器中的代码非常简单,就是vars.put生成一个JMeter参数
每个脚本,我们设置为300VU,500TPS,执行5分钟,采用CLI方式执行,执行完后,切割中间的3分钟生成报告,服务器的硬件为8核CPUE7-4820。具体执行结果如下:
从试验结果可以得出如下几个很明显的现象:
JSR233组件下的BeanShell性能非常差。
同一个场景中,如果有的脚本使用了JSR233组件下的BeanShell语言,那会严重影响当前场景下的所有BeanShell组件模块的性能;同时也会稍微影响JSR233组件下的Groovy语言的性能,导致其TPS略有下降。
BeanShell组件下的BeanShell语言性能比JSR233组件下的Groovy语言性能稍差,实测TPS基本一致。
通过本次试验,在此提醒大家,在编写JMeter脚本的时候,千万不要使用JSR233组件下的BeanShell语言,如果要使用BeanShell语言一定要用BeanShell组件下的。
喜欢请长按下方二维码关注我的个人微信号,测试杂货铺。^_^
Groovy和BeanShell性能比较.JMX的源文件如下,复制然后保存成jmx就可以在JMeter中使用:
- <?xml version="1.0" encoding="UTF-8"?>
- <jmeterTestPlan version="1.2" properties="5.0" jmeter="5.1 r1853635">
- <hashTree>
- <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
- <stringProp name="TestPlan.comments"></stringProp>
- <boolProp name="TestPlan.functional_mode">false</boolProp>
- <boolProp name="TestPlan.tearDown_on_shutdown">true</boolProp>
- <boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
- <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
- <collectionProp name="Arguments.arguments"/>
- </elementProp>
- <stringProp name="TestPlan.user_define_classpath"></stringProp>
- </TestPlan>
- <hashTree>
- <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group Groovy" enabled="true">
- <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
- <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
- <boolProp name="LoopController.continue_forever">false</boolProp>
- <intProp name="LoopController.loops">-1</intProp>
- </elementProp>
- <stringProp name="ThreadGroup.num_threads">300</stringProp>
- <stringProp name="ThreadGroup.ramp_time">10</stringProp>
- <boolProp name="ThreadGroup.scheduler">true</boolProp>
- <stringProp name="ThreadGroup.duration">300</stringProp>
- <stringProp name="ThreadGroup.delay"></stringProp>
- </ThreadGroup>
- <hashTree>
- <kg.apc.jmeter.samplers.DummySampler guiclass="kg.apc.jmeter.samplers.DummySamplerGui" testclass="kg.apc.jmeter.samplers.DummySampler" testname="DummyGroovy" enabled="true">
- <boolProp name="WAITING">true</boolProp>
- <boolProp name="SUCCESFULL">true</boolProp>
- <stringProp name="RESPONSE_CODE">200</stringProp>
- <stringProp name="RESPONSE_MESSAGE">OK</stringProp>
- <stringProp name="REQUEST_DATA">${testvars1}</stringProp>
- <stringProp name="RESPONSE_DATA">Dummy Sampler used to simulate requests and responses
- without actual network activity. This helps debugging tests.</stringProp>
- <stringProp name="RESPONSE_TIME">${__Random(50,500)}</stringProp>
- <stringProp name="LATENCY">${__Random(1,50)}</stringProp>
- <stringProp name="CONNECT">${__Random(1,5)}</stringProp>
- </kg.apc.jmeter.samplers.DummySampler>
- <hashTree>
- <JSR223PreProcessor guiclass="TestBeanGUI" testclass="JSR223PreProcessor" testname="JSR223 PreProcessor" enabled="true">
- <stringProp name="cacheKey">true</stringProp>
- <stringProp name="filename"></stringProp>
- <stringProp name="parameters"></stringProp>
- <stringProp name="script">vars.put("testvars1","testvars1Groovy")</stringProp>
- <stringProp name="scriptLanguage">groovy</stringProp>
- </JSR223PreProcessor>
- <hashTree/>
- </hashTree>
- <ConstantThroughputTimer guiclass="TestBeanGUI" testclass="ConstantThroughputTimer" testname="Constant Throughput Timer" enabled="true">
- <intProp name="calcMode">2</intProp>
- <doubleProp>
- <name>throughput</name>
- <value>30000.0</value>
- <savedValue>0.0</savedValue>
- </doubleProp>
- </ConstantThroughputTimer>
- <hashTree/>
- </hashTree>
- <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group JSR233BeanShell" enabled="true">
- <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
- <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
- <boolProp name="LoopController.continue_forever">false</boolProp>
- <intProp name="LoopController.loops">-1</intProp>
- </elementProp>
- <stringProp name="ThreadGroup.num_threads">300</stringProp>
- <stringProp name="ThreadGroup.ramp_time">10</stringProp>
- <boolProp name="ThreadGroup.scheduler">true</boolProp>
- <stringProp name="ThreadGroup.duration">300</stringProp>
- <stringProp name="ThreadGroup.delay"></stringProp>
- </ThreadGroup>
- <hashTree>
- <kg.apc.jmeter.samplers.DummySampler guiclass="kg.apc.jmeter.samplers.DummySamplerGui" testclass="kg.apc.jmeter.samplers.DummySampler" testname="DummyJSR233BeanShell" enabled="true">
- <boolProp name="WAITING">true</boolProp>
- <boolProp name="SUCCESFULL">true</boolProp>
- <stringProp name="RESPONSE_CODE">200</stringProp>
- <stringProp name="RESPONSE_MESSAGE">OK</stringProp>
- <stringProp name="REQUEST_DATA">${testvars1}</stringProp>
- <stringProp name="RESPONSE_DATA">Dummy Sampler used to simulate requests and responses
- without actual network activity. This helps debugging tests.</stringProp>
- <stringProp name="RESPONSE_TIME">${__Random(50,500)}</stringProp>
- <stringProp name="LATENCY">${__Random(1,50)}</stringProp>
- <stringProp name="CONNECT">${__Random(1,5)}</stringProp>
- </kg.apc.jmeter.samplers.DummySampler>
- <hashTree>
- <JSR223PreProcessor guiclass="TestBeanGUI" testclass="JSR223PreProcessor" testname="JSR223 PreProcessor" enabled="true">
- <stringProp name="scriptLanguage">beanshell</stringProp>
- <stringProp name="parameters"></stringProp>
- <stringProp name="filename"></stringProp>
- <stringProp name="cacheKey">true</stringProp>
- <stringProp name="script">vars.put("testvars1","testvars1BeanShell");</stringProp>
- </JSR223PreProcessor>
- <hashTree/>
- </hashTree>
- <ConstantThroughputTimer guiclass="TestBeanGUI" testclass="ConstantThroughputTimer" testname="Constant Throughput Timer" enabled="true">
- <intProp name="calcMode">2</intProp>
- <doubleProp>
- <name>throughput</name>
- <value>30000.0</value>
- <savedValue>0.0</savedValue>
- </doubleProp>
- </ConstantThroughputTimer>
- <hashTree/>
- </hashTree>
- <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group BeanShellBeanShell" enabled="true">
- <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
- <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
- <boolProp name="LoopController.continue_forever">false</boolProp>
- <intProp name="LoopController.loops">-1</intProp>
- </elementProp>
- <stringProp name="ThreadGroup.num_threads">300</stringProp>
- <stringProp name="ThreadGroup.ramp_time">10</stringProp>
- <boolProp name="ThreadGroup.scheduler">true</boolProp>
- <stringProp name="ThreadGroup.duration">300</stringProp>
- <stringProp name="ThreadGroup.delay"></stringProp>
- </ThreadGroup>
- <hashTree>
- <kg.apc.jmeter.samplers.DummySampler guiclass="kg.apc.jmeter.samplers.DummySamplerGui" testclass="kg.apc.jmeter.samplers.DummySampler" testname="DummyBeanShell" enabled="true">
- <boolProp name="WAITING">true</boolProp>
- <boolProp name="SUCCESFULL">true</boolProp>
- <stringProp name="RESPONSE_CODE">200</stringProp>
- <stringProp name="RESPONSE_MESSAGE">OK</stringProp>
- <stringProp name="REQUEST_DATA">${testvars1}</stringProp>
- <stringProp name="RESPONSE_DATA">Dummy Sampler used to simulate requests and responses
- without actual network activity. This helps debugging tests.</stringProp>
- <stringProp name="RESPONSE_TIME">${__Random(50,500)}</stringProp>
- <stringProp name="LATENCY">${__Random(1,50)}</stringProp>
- <stringProp name="CONNECT">${__Random(1,5)}</stringProp>
- </kg.apc.jmeter.samplers.DummySampler>
- <hashTree>
- <BeanShellPreProcessor guiclass="TestBeanGUI" testclass="BeanShellPreProcessor" testname="BeanShell PreProcessor" enabled="true">
- <stringProp name="filename"></stringProp>
- <stringProp name="parameters"></stringProp>
- <boolProp name="resetInterpreter">false</boolProp>
- <stringProp name="script">vars.put("testvars1","testvars1BeanShell");</stringProp>
- </BeanShellPreProcessor>
- <hashTree/>
- </hashTree>
- <ConstantThroughputTimer guiclass="TestBeanGUI" testclass="ConstantThroughputTimer" testname="Constant Throughput Timer" enabled="true">
- <intProp name="calcMode">2</intProp>
- <doubleProp>
- <name>throughput</name>
- <value>30000.0</value>
- <savedValue>0.0</savedValue>
- </doubleProp>
- </ConstantThroughputTimer>
- <hashTree/>
- </hashTree>
- <ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="false">
- <boolProp name="ResultCollector.error_logging">false</boolProp>
- <objProp>
- <name>saveConfig</name>
- <value class="SampleSaveConfiguration">
- <time>true</time>
- <latency>true</latency>
- <timestamp>true</timestamp>
- <success>true</success>
- <label>true</label>
- <code>true</code>
- <message>true</message>
- <threadName>true</threadName>
- <dataType>true</dataType>
- <encoding>false</encoding>
- <assertions>true</assertions>
- <subresults>true</subresults>
- <responseData>false</responseData>
- <samplerData>false</samplerData>
- <xml>false</xml>
- <fieldNames>true</fieldNames>
- <responseHeaders>false</responseHeaders>
- <requestHeaders>false</requestHeaders>
- <responseDataOnError>false</responseDataOnError>
- <saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
- <assertionsResultsToSave>0</assertionsResultsToSave>
- <bytes>true</bytes>
- <sentBytes>true</sentBytes>
- <url>true</url>
- <threadCounts>true</threadCounts>
- <idleTime>true</idleTime>
- <connectTime>true</connectTime>
- </value>
- </objProp>
- <stringProp name="filename"></stringProp>
- </ResultCollector>
- <hashTree/>
- <ResultCollector guiclass="SummaryReport" testclass="ResultCollector" testname="Summary Report" enabled="true">
- <boolProp name="ResultCollector.error_logging">false</boolProp>
- <objProp>
- <name>saveConfig</name>
- <value class="SampleSaveConfiguration">
- <time>true</time>
- <latency>true</latency>
- <timestamp>true</timestamp>
- <success>true</success>
- <label>true</label>
- <code>true</code>
- <message>true</message>
- <threadName>true</threadName>
- <dataType>true</dataType>
- <encoding>false</encoding>
- <assertions>true</assertions>
- <subresults>true</subresults>
- <responseData>false</responseData>
- <samplerData>false</samplerData>
- <xml>false</xml>
- <fieldNames>true</fieldNames>
- <responseHeaders>false</responseHeaders>
- <requestHeaders>false</requestHeaders>
- <responseDataOnError>false</responseDataOnError>
- <saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
- <assertionsResultsToSave>0</assertionsResultsToSave>
- <bytes>true</bytes>
- <sentBytes>true</sentBytes>
- <url>true</url>
- <threadCounts>true</threadCounts>
- <idleTime>true</idleTime>
- <connectTime>true</connectTime>
- </value>
- </objProp>
- <stringProp name="filename"></stringProp>
- </ResultCollector>
- <hashTree/>
- </hashTree>
- </hashTree>
- </jmeterTestPlan>
JMeter下Groovy和BeanShell语言在不同组件中性能差异实践探究的更多相关文章
- linux终端下 编译c语言程序
linux终端下,编译C语言程序步骤为: 采用vi进行源代码编写,编写完成后,:wq存盘退出,如: vi test.c 在命令行下,运行gcc编译程序,生成执行码,如: gcc -o test te ...
- Linux centos 7/ubantu下: 用 C 语言连接 MySQL数据库
前言:最近用IPC.socket做ATM.聊天项目,考虑到需要用到数据库,所以总结一下centos.ubantu环境下怎么用C语言操作数据库,例如常见的增删改查等! 一.Centos环境安装mysql ...
- ubuntu下如何编译C语言
ubuntu下如何编译C语言 如果没有gcc编译器的话,使用以下命令获取 ~# sudo apt-get install gcc同时要下载辅助工具 ~# sudo apt-get instal ...
- Ubuntu下在Eclipse IDE for C/C++ Developers中怎样执行C语言的GTK程序?(已解决)
(已解决.详见Ubuntu 12.04下在Eclipse IDE for C/C++ Developers中执行C语言的GTK程序) 按"Ubuntu下GTK的安装.编译和測试"( ...
- linux环境下安装可操作图库语言Gremlin的图框架HugeGraph
原创/朱季谦 图数据库是一项比较前沿而逐渐热门的技术,是NoSql数据库的一种,它应用图形理论存储实体之间的关系信息,最主要的组成有两种,结点集和连接结点的边.常见的图数据库有Neo4j,Januas ...
- Linux系统下C语言如何调用scalapack中的函数
在并行计算中经常需要调用scalapck(并行化的lapack)函数库里面的函数进行编程,这里简单介绍在C语言如何调用scalapck中的矩阵向量乘的函数. 注意:scalapack中的函数是用for ...
- C++下混合编译c语言方法总结
最近在读SGI STL源码,感觉对C++的学习很有帮助,之前对于泛型.iterator.traits等等各种特性的概念非常模糊,通过这两天的琢磨,再加上<STL 源码剖析>的帮助,对C++ ...
- 转载~kxcfzyk:Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解
Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解 多线程c语言linuxsemaphore条件变量 (本文的读者定位是了解Pthread常用多线程API和Pthread互斥锁 ...
- Swift - 使用下划线(_)来分隔数值中的数字
为了增强较大数值的可读性,Swift语言增加了下划线(_)来分隔数值中的数字. 不管是整数,还是浮点数,都可以使用下划线来分隔数字. 1 2 3 4 //数值可读性 let value1 = 10_0 ...
随机推荐
- 多路I/O复用(select、poll、epoll)的比较学习:
elect.poll.epoll之间的区别总结[整理] 转自:http://www.cnblogs.com/Anker/p/3265058.html select,poll,epoll都是IO多 ...
- "函中函" -------------------- func2(func) -------------- 函数名可以当做函数的参数
def func(): print("吃了么")def func2(fn): print("我是func2") fn() # 执⾏传递过来的fn # 即 fn替 ...
- 开发一个shopify插件
开发一个shopify插件,shopify商城可以安装该插件:当用户在商城下单后,插件把订单数据按照指定格式传给disruptsports服务器: https://help.shopify. ...
- Elementary Sorts
初级排序 rules of the game 排序是很常见的需求,把数字从小到大排,把字符串按字典序排等等,目标是能对任何类型的数据进行排序,这可以通过回调(callback)实现: Java 用接口 ...
- Data Compression
数据压缩 introduction 压缩数据可以节省存储数据需要的空间和传输数据需要的时间,虽然摩尔定律说集成芯片上的晶体管每 18-24 个月翻一倍,帕金森定律说数据会自己拓展来填满可用空间,但数据 ...
- awk.md
简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的行编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分 ...
- __autoreleasing 与 局部变量
__autoreleasing 修饰的变量不是局部变量: 它的生命周期由autoreleasepool负责: +(Reachability*)reachabilityWithHostname:(NSS ...
- logstash 匹配日志格式
2017-05-15 12:06:17 INFO me.cinyi.imapp.push.commons.iospush - 用户ID[1000]-标识[11500], admin推送通知成功, ...
- Error: Couldn't find preset "env" relative to directory "/Users/user/ethereumjs-vm"
运行npm run build时遇见这个问题,解决办法是安装: npm install --save-dev babel-preset-env 就解决了
- Ubuntu下查看自己的GPU型号
1.在命令行中输入:lspci 即可看到当前显卡型号. 2.Ubuntu 14.04 安装 Nvidia 私有驱动 sudo apt-get install nvidia-331 3.进行双显卡切换n ...