一般而言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中使用:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <jmeterTestPlan version="1.2" properties="5.0" jmeter="5.1 r1853635">
  3. <hashTree>
  4. <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
  5. <stringProp name="TestPlan.comments"></stringProp>
  6. <boolProp name="TestPlan.functional_mode">false</boolProp>
  7. <boolProp name="TestPlan.tearDown_on_shutdown">true</boolProp>
  8. <boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
  9. <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
  10. <collectionProp name="Arguments.arguments"/>
  11. </elementProp>
  12. <stringProp name="TestPlan.user_define_classpath"></stringProp>
  13. </TestPlan>
  14. <hashTree>
  15. <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group Groovy" enabled="true">
  16. <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
  17. <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
  18. <boolProp name="LoopController.continue_forever">false</boolProp>
  19. <intProp name="LoopController.loops">-1</intProp>
  20. </elementProp>
  21. <stringProp name="ThreadGroup.num_threads">300</stringProp>
  22. <stringProp name="ThreadGroup.ramp_time">10</stringProp>
  23. <boolProp name="ThreadGroup.scheduler">true</boolProp>
  24. <stringProp name="ThreadGroup.duration">300</stringProp>
  25. <stringProp name="ThreadGroup.delay"></stringProp>
  26. </ThreadGroup>
  27. <hashTree>
  28. <kg.apc.jmeter.samplers.DummySampler guiclass="kg.apc.jmeter.samplers.DummySamplerGui" testclass="kg.apc.jmeter.samplers.DummySampler" testname="DummyGroovy" enabled="true">
  29. <boolProp name="WAITING">true</boolProp>
  30. <boolProp name="SUCCESFULL">true</boolProp>
  31. <stringProp name="RESPONSE_CODE">200</stringProp>
  32. <stringProp name="RESPONSE_MESSAGE">OK</stringProp>
  33. <stringProp name="REQUEST_DATA">${testvars1}</stringProp>
  34. <stringProp name="RESPONSE_DATA">Dummy Sampler used to simulate requests and responses
  35. without actual network activity. This helps debugging tests.</stringProp>
  36. <stringProp name="RESPONSE_TIME">${__Random(50,500)}</stringProp>
  37. <stringProp name="LATENCY">${__Random(1,50)}</stringProp>
  38. <stringProp name="CONNECT">${__Random(1,5)}</stringProp>
  39. </kg.apc.jmeter.samplers.DummySampler>
  40. <hashTree>
  41. <JSR223PreProcessor guiclass="TestBeanGUI" testclass="JSR223PreProcessor" testname="JSR223 PreProcessor" enabled="true">
  42. <stringProp name="cacheKey">true</stringProp>
  43. <stringProp name="filename"></stringProp>
  44. <stringProp name="parameters"></stringProp>
  45. <stringProp name="script">vars.put("testvars1","testvars1Groovy")</stringProp>
  46. <stringProp name="scriptLanguage">groovy</stringProp>
  47. </JSR223PreProcessor>
  48. <hashTree/>
  49. </hashTree>
  50. <ConstantThroughputTimer guiclass="TestBeanGUI" testclass="ConstantThroughputTimer" testname="Constant Throughput Timer" enabled="true">
  51. <intProp name="calcMode">2</intProp>
  52. <doubleProp>
  53. <name>throughput</name>
  54. <value>30000.0</value>
  55. <savedValue>0.0</savedValue>
  56. </doubleProp>
  57. </ConstantThroughputTimer>
  58. <hashTree/>
  59. </hashTree>
  60. <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group JSR233BeanShell" enabled="true">
  61. <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
  62. <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
  63. <boolProp name="LoopController.continue_forever">false</boolProp>
  64. <intProp name="LoopController.loops">-1</intProp>
  65. </elementProp>
  66. <stringProp name="ThreadGroup.num_threads">300</stringProp>
  67. <stringProp name="ThreadGroup.ramp_time">10</stringProp>
  68. <boolProp name="ThreadGroup.scheduler">true</boolProp>
  69. <stringProp name="ThreadGroup.duration">300</stringProp>
  70. <stringProp name="ThreadGroup.delay"></stringProp>
  71. </ThreadGroup>
  72. <hashTree>
  73. <kg.apc.jmeter.samplers.DummySampler guiclass="kg.apc.jmeter.samplers.DummySamplerGui" testclass="kg.apc.jmeter.samplers.DummySampler" testname="DummyJSR233BeanShell" enabled="true">
  74. <boolProp name="WAITING">true</boolProp>
  75. <boolProp name="SUCCESFULL">true</boolProp>
  76. <stringProp name="RESPONSE_CODE">200</stringProp>
  77. <stringProp name="RESPONSE_MESSAGE">OK</stringProp>
  78. <stringProp name="REQUEST_DATA">${testvars1}</stringProp>
  79. <stringProp name="RESPONSE_DATA">Dummy Sampler used to simulate requests and responses
  80. without actual network activity. This helps debugging tests.</stringProp>
  81. <stringProp name="RESPONSE_TIME">${__Random(50,500)}</stringProp>
  82. <stringProp name="LATENCY">${__Random(1,50)}</stringProp>
  83. <stringProp name="CONNECT">${__Random(1,5)}</stringProp>
  84. </kg.apc.jmeter.samplers.DummySampler>
  85. <hashTree>
  86. <JSR223PreProcessor guiclass="TestBeanGUI" testclass="JSR223PreProcessor" testname="JSR223 PreProcessor" enabled="true">
  87. <stringProp name="scriptLanguage">beanshell</stringProp>
  88. <stringProp name="parameters"></stringProp>
  89. <stringProp name="filename"></stringProp>
  90. <stringProp name="cacheKey">true</stringProp>
  91. <stringProp name="script">vars.put("testvars1","testvars1BeanShell");</stringProp>
  92. </JSR223PreProcessor>
  93. <hashTree/>
  94. </hashTree>
  95. <ConstantThroughputTimer guiclass="TestBeanGUI" testclass="ConstantThroughputTimer" testname="Constant Throughput Timer" enabled="true">
  96. <intProp name="calcMode">2</intProp>
  97. <doubleProp>
  98. <name>throughput</name>
  99. <value>30000.0</value>
  100. <savedValue>0.0</savedValue>
  101. </doubleProp>
  102. </ConstantThroughputTimer>
  103. <hashTree/>
  104. </hashTree>
  105. <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group BeanShellBeanShell" enabled="true">
  106. <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
  107. <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
  108. <boolProp name="LoopController.continue_forever">false</boolProp>
  109. <intProp name="LoopController.loops">-1</intProp>
  110. </elementProp>
  111. <stringProp name="ThreadGroup.num_threads">300</stringProp>
  112. <stringProp name="ThreadGroup.ramp_time">10</stringProp>
  113. <boolProp name="ThreadGroup.scheduler">true</boolProp>
  114. <stringProp name="ThreadGroup.duration">300</stringProp>
  115. <stringProp name="ThreadGroup.delay"></stringProp>
  116. </ThreadGroup>
  117. <hashTree>
  118. <kg.apc.jmeter.samplers.DummySampler guiclass="kg.apc.jmeter.samplers.DummySamplerGui" testclass="kg.apc.jmeter.samplers.DummySampler" testname="DummyBeanShell" enabled="true">
  119. <boolProp name="WAITING">true</boolProp>
  120. <boolProp name="SUCCESFULL">true</boolProp>
  121. <stringProp name="RESPONSE_CODE">200</stringProp>
  122. <stringProp name="RESPONSE_MESSAGE">OK</stringProp>
  123. <stringProp name="REQUEST_DATA">${testvars1}</stringProp>
  124. <stringProp name="RESPONSE_DATA">Dummy Sampler used to simulate requests and responses
  125. without actual network activity. This helps debugging tests.</stringProp>
  126. <stringProp name="RESPONSE_TIME">${__Random(50,500)}</stringProp>
  127. <stringProp name="LATENCY">${__Random(1,50)}</stringProp>
  128. <stringProp name="CONNECT">${__Random(1,5)}</stringProp>
  129. </kg.apc.jmeter.samplers.DummySampler>
  130. <hashTree>
  131. <BeanShellPreProcessor guiclass="TestBeanGUI" testclass="BeanShellPreProcessor" testname="BeanShell PreProcessor" enabled="true">
  132. <stringProp name="filename"></stringProp>
  133. <stringProp name="parameters"></stringProp>
  134. <boolProp name="resetInterpreter">false</boolProp>
  135. <stringProp name="script">vars.put("testvars1","testvars1BeanShell");</stringProp>
  136. </BeanShellPreProcessor>
  137. <hashTree/>
  138. </hashTree>
  139. <ConstantThroughputTimer guiclass="TestBeanGUI" testclass="ConstantThroughputTimer" testname="Constant Throughput Timer" enabled="true">
  140. <intProp name="calcMode">2</intProp>
  141. <doubleProp>
  142. <name>throughput</name>
  143. <value>30000.0</value>
  144. <savedValue>0.0</savedValue>
  145. </doubleProp>
  146. </ConstantThroughputTimer>
  147. <hashTree/>
  148. </hashTree>
  149. <ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="false">
  150. <boolProp name="ResultCollector.error_logging">false</boolProp>
  151. <objProp>
  152. <name>saveConfig</name>
  153. <value class="SampleSaveConfiguration">
  154. <time>true</time>
  155. <latency>true</latency>
  156. <timestamp>true</timestamp>
  157. <success>true</success>
  158. <label>true</label>
  159. <code>true</code>
  160. <message>true</message>
  161. <threadName>true</threadName>
  162. <dataType>true</dataType>
  163. <encoding>false</encoding>
  164. <assertions>true</assertions>
  165. <subresults>true</subresults>
  166. <responseData>false</responseData>
  167. <samplerData>false</samplerData>
  168. <xml>false</xml>
  169. <fieldNames>true</fieldNames>
  170. <responseHeaders>false</responseHeaders>
  171. <requestHeaders>false</requestHeaders>
  172. <responseDataOnError>false</responseDataOnError>
  173. <saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
  174. <assertionsResultsToSave>0</assertionsResultsToSave>
  175. <bytes>true</bytes>
  176. <sentBytes>true</sentBytes>
  177. <url>true</url>
  178. <threadCounts>true</threadCounts>
  179. <idleTime>true</idleTime>
  180. <connectTime>true</connectTime>
  181. </value>
  182. </objProp>
  183. <stringProp name="filename"></stringProp>
  184. </ResultCollector>
  185. <hashTree/>
  186. <ResultCollector guiclass="SummaryReport" testclass="ResultCollector" testname="Summary Report" enabled="true">
  187. <boolProp name="ResultCollector.error_logging">false</boolProp>
  188. <objProp>
  189. <name>saveConfig</name>
  190. <value class="SampleSaveConfiguration">
  191. <time>true</time>
  192. <latency>true</latency>
  193. <timestamp>true</timestamp>
  194. <success>true</success>
  195. <label>true</label>
  196. <code>true</code>
  197. <message>true</message>
  198. <threadName>true</threadName>
  199. <dataType>true</dataType>
  200. <encoding>false</encoding>
  201. <assertions>true</assertions>
  202. <subresults>true</subresults>
  203. <responseData>false</responseData>
  204. <samplerData>false</samplerData>
  205. <xml>false</xml>
  206. <fieldNames>true</fieldNames>
  207. <responseHeaders>false</responseHeaders>
  208. <requestHeaders>false</requestHeaders>
  209. <responseDataOnError>false</responseDataOnError>
  210. <saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
  211. <assertionsResultsToSave>0</assertionsResultsToSave>
  212. <bytes>true</bytes>
  213. <sentBytes>true</sentBytes>
  214. <url>true</url>
  215. <threadCounts>true</threadCounts>
  216. <idleTime>true</idleTime>
  217. <connectTime>true</connectTime>
  218. </value>
  219. </objProp>
  220. <stringProp name="filename"></stringProp>
  221. </ResultCollector>
  222. <hashTree/>
  223. </hashTree>
  224. </hashTree>
  225. </jmeterTestPlan>

JMeter下Groovy和BeanShell语言在不同组件中性能差异实践探究的更多相关文章

  1. linux终端下 编译c语言程序

    linux终端下,编译C语言程序步骤为: 采用vi进行源代码编写,编写完成后,:wq存盘退出,如: vi test.c 在命令行下,运行gcc编译程序,生成执行码,如: gcc  -o test te ...

  2. Linux centos 7/ubantu下: 用 C 语言连接 MySQL数据库

    前言:最近用IPC.socket做ATM.聊天项目,考虑到需要用到数据库,所以总结一下centos.ubantu环境下怎么用C语言操作数据库,例如常见的增删改查等! 一.Centos环境安装mysql ...

  3. ubuntu下如何编译C语言

    ubuntu下如何编译C语言     如果没有gcc编译器的话,使用以下命令获取 ~# sudo apt-get install gcc同时要下载辅助工具 ~# sudo apt-get instal ...

  4. Ubuntu下在Eclipse IDE for C/C++ Developers中怎样执行C语言的GTK程序?(已解决)

    (已解决.详见Ubuntu 12.04下在Eclipse IDE for C/C++ Developers中执行C语言的GTK程序) 按"Ubuntu下GTK的安装.编译和測试"( ...

  5. linux环境下安装可操作图库语言Gremlin的图框架HugeGraph

    原创/朱季谦 图数据库是一项比较前沿而逐渐热门的技术,是NoSql数据库的一种,它应用图形理论存储实体之间的关系信息,最主要的组成有两种,结点集和连接结点的边.常见的图数据库有Neo4j,Januas ...

  6. Linux系统下C语言如何调用scalapack中的函数

    在并行计算中经常需要调用scalapck(并行化的lapack)函数库里面的函数进行编程,这里简单介绍在C语言如何调用scalapck中的矩阵向量乘的函数. 注意:scalapack中的函数是用for ...

  7. C++下混合编译c语言方法总结

    最近在读SGI STL源码,感觉对C++的学习很有帮助,之前对于泛型.iterator.traits等等各种特性的概念非常模糊,通过这两天的琢磨,再加上<STL 源码剖析>的帮助,对C++ ...

  8. 转载~kxcfzyk:Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解

    Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解   多线程c语言linuxsemaphore条件变量 (本文的读者定位是了解Pthread常用多线程API和Pthread互斥锁 ...

  9. Swift - 使用下划线(_)来分隔数值中的数字

    为了增强较大数值的可读性,Swift语言增加了下划线(_)来分隔数值中的数字. 不管是整数,还是浮点数,都可以使用下划线来分隔数字. 1 2 3 4 //数值可读性 let value1 = 10_0 ...

随机推荐

  1. 多路I/O复用(select、poll、epoll)的比较学习:

    elect.poll.epoll之间的区别总结[整理]  转自:http://www.cnblogs.com/Anker/p/3265058.html   select,poll,epoll都是IO多 ...

  2. "函中函" -------------------- func2(func) -------------- 函数名可以当做函数的参数

    def func(): print("吃了么")def func2(fn): print("我是func2") fn() # 执⾏传递过来的fn # 即 fn替 ...

  3. 开发一个shopify插件

       开发一个shopify插件,shopify商城可以安装该插件:当用户在商城下单后,插件把订单数据按照指定格式传给disruptsports服务器:   https://help.shopify. ...

  4. Elementary Sorts

    初级排序 rules of the game 排序是很常见的需求,把数字从小到大排,把字符串按字典序排等等,目标是能对任何类型的数据进行排序,这可以通过回调(callback)实现: Java 用接口 ...

  5. Data Compression

    数据压缩 introduction 压缩数据可以节省存储数据需要的空间和传输数据需要的时间,虽然摩尔定律说集成芯片上的晶体管每 18-24 个月翻一倍,帕金森定律说数据会自己拓展来填满可用空间,但数据 ...

  6. awk.md

    简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的行编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分 ...

  7. __autoreleasing 与 局部变量

    __autoreleasing 修饰的变量不是局部变量: 它的生命周期由autoreleasepool负责: +(Reachability*)reachabilityWithHostname:(NSS ...

  8. logstash 匹配日志格式

    2017-05-15 12:06:17 INFO  me.cinyi.imapp.push.commons.iospush  - 用户ID[1000]-标识[11500], admin推送通知成功, ...

  9. Error: Couldn't find preset "env" relative to directory "/Users/user/ethereumjs-vm"

    运行npm run build时遇见这个问题,解决办法是安装: npm install --save-dev babel-preset-env 就解决了

  10. Ubuntu下查看自己的GPU型号

    1.在命令行中输入:lspci 即可看到当前显卡型号. 2.Ubuntu 14.04 安装 Nvidia 私有驱动 sudo apt-get install nvidia-331 3.进行双显卡切换n ...