jmeter结果合并_【NO.14】jmeter-处理结果

本文介绍了使用多台测试机对服务器发送大量请求的原因,是因单台测试机配置弱,难以模拟大量并发用户。还详细阐述了合并两台测试机Jmeter测试结果的步骤,包括去除标题行、重命名、压缩、下载、上传、解压缩、合并结果集及计算TPS等,使用了vi、cp等Linux命令。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在1台测试机上面处理测试结果并没啥,比较麻烦的是合并2台测试机的测试结果。

首先说说,为什么我们需要使用2台(甚至3台、4台)测试机对服务器发送大量的请求呢?说白了就是测试机配置太弱了,服务器太牛逼。有时候我的测试机是4核的,但是服务器居然是16核、32核。如果测试机也是32核的话,只用1台测试机就能搞定工作。

引用一段比较专业的说法

作为一个纯 JAVA 的GUI应用,JMeter对于CPU和内存的消耗还是很惊人的,所以当需要模拟数以千计的并发用户时,使用单台机器模拟所有的并发用户就有些力不从心,甚至还会引起JAVA内存溢出的错误。不过,JMeter也可以像 LoadRunner 一样通过使用多台机器运行所谓的代理来分担负载产生器自身的压力,并借此来获取更大的并发用户数。

上面这段话也可以归结为:测试机的配置太弱了,但凡是16核的测试机,Jmeter对于CPU和内存再消耗惊人,能怎么样?完全HOLD住。

-------------------------------------------------------------------------------------------------------------------------------------------------------------

下面的内容仅仅是叙述了我如何合并2台测试机的测试结果,用到的Linux命令包括:vi、cp、tar、rz、sz、cat。熟能生巧,没啥太特别的东西,备份一下以免长期不用忘了咋用。

-------------------------------------------------------------------------------------------------------------------------------------------------------------

举例开始了,我们假设只有2台测试机,所以只需要将2个测试结果文件合并就可以了:

//将2台测试机/result目录下的result.csv文件通过vi打开,去掉首行然后保存。因为首行显示的是jmeter-configure的标题(如下图),会影响结果的计算

//接下来操作都是在这两台测试机的/result目录下执行,!!!!别去其它目录!!!!!!

# vi result.csv

去除行首的标题后,保存并退出

//在其中1台测试机内(叫它测试机a),将测试结果文件重新命名(原名是:result.csv),原因是我们在执行多台测试机并发的时候,在每台测试机保存的结果文件的名字是相同的。所以需要将名字修改成不相同的,以便执行合并结果的操作

//cp 已有文件名 新文件名

# cp result.csv  result01.csv

//在测试机a的操作界面内,将已经重新命名的结果文件压缩

//tar –zcvf 文件名.tar.gz  文件名

#tar –zcvf result01.csv.tar.gz result01.csv

//在测试机a的操作界面内,将已压缩的结果文件从测试机a下载到本地

#sz result01.csv.tar.gz

//切换到另1台测试机的界面(叫它测试机b),

//在测试机b的操作界面内,上传已经保存在本地的测试机a的结果文件到测试机b

#rz

选择文件result01.csv.tar.gz,确认

//在测试机b的操作界面内,解压缩测试机a的结果文件

#tar –zxvf result01.csv.tar.gz

//在测试机b的操作界面内,合并结果集(此时体现了重新命名测试结果文件的意义)

//将测试机a的已重新命名的测试结果文件(原名是:result.csv,重新命名后的文件名:result01.csv)追加到测试机b的测试结果文件内,合并为1个文件以便计算测试结果

#cat result01.csv >> result.csv

//在测试机b的操作界面内,统计测试结果并且计算TPS

#wc -l result.csv

服务器的总响应数目 / 脚本运行时间 = TPS

javax.script.ScriptException: javax.script.ScriptException: groovy.lang.MissingMethodException: No signature of method: org.apache.jmeter.protocol.http.control.HeaderManager.getHeaderNamed() is applicable for argument types: (java.lang.String) values: [Content-Type] Possible solutions: getFirstHeaderNamed(java.lang.String), removeHeaderNamed(java.lang.String) at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:158) at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:233) at org.apache.jmeter.util.JSR223TestElement.processFileOrScript(JSR223TestElement.java:219) at org.apache.jmeter.modifiers.UTPJSR223PreProcessor.process(UTPJSR223PreProcessor.java:109) at org.apache.jmeter.threads.JMeterThread.runPreProcessors(JMeterThread.java:965) at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:549) at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:489) at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:256) at java.lang.Thread.run(Thread.java:748) Caused by: javax.script.ScriptException: groovy.lang.MissingMethodException: No signature of method: org.apache.jmeter.protocol.http.control.HeaderManager.getHeaderNamed() is applicable for argument types: (java.lang.String) values: [Content-Type] Possible solutions: getFirstHeaderNamed(java.lang.String), removeHeaderNamed(java.lang.String) at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:320) at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:155) ... 8 more Caused by: groovy.lang.MissingMethodException: No signature of method: org.apache.jmeter.protocol.http.control.HeaderManager.getHeaderNamed() is applicable for argument types: (java.lang.String) values: [Content-Type] Possible solutions: getFirstHeaderNamed(java.lang.String), removeHeaderNamed(java.lang.String) at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:58) at org.codehaus.groovy.runtime.callsite.PojoMetaClassSite.call(PojoMetaClassSite.java:49) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) at Script758.run(Script758.groovy:10) at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:317) ... 9 more
07-01
<think>我们注意到用户提供的代码片段中存在一个错误:在Groovy中,当使用正则表达式匹配时,如果使用`find()`方法,那么匹配结果应该通过`matcher`对象来获取,而不是使用`it`(在闭包中,`it`代表当前元素,而不是匹配结果)。此外,代码中使用了`it[0]`,但这里的`it`实际上指的是`item`,而不是匹配器。因此,我们需要修正这个错误。 ### 修正后的代码 ```groovy def numbers = codes.collect { item -> // 创建匹配器 def matcher = (item =~ /\d+/) // 如果找到匹配,则取第一个匹配的字符串并转为整数;否则返回0 matcher.find() ? matcher.group().toInteger() : 0 } ``` ### 解释 1. **创建匹配器**:`(item =~ /\d+/)` 创建一个匹配器,用于在字符串`item`中查找连续的数字。 2. **查找匹配**:`matcher.find()` 尝试查找下一个匹配项。如果找到,返回`true`;否则返回`false`。 3. **获取匹配值**:当`matcher.find()`为`true`时,`matcher.group()`返回当前匹配的整个字符串(即第一个匹配的连续数字)。然后将其转换为整数。 4. **未找到匹配**:返回0。 ### 注意事项 - 如果字符串中有多个数字,`matcher.find()`只取第一个匹配的数字。如果需要最后一个或者最大的数字,则需要调整逻辑。 - 如果数字可能很大,注意`toInteger()`的范围(最大`Integer.MAX_VALUE`即2147483647)。如果超过,可以使用`toLong()`。 ### 示例 假设`codes`列表为:`["test1", "test23", "test456", "noNumber"]` 则`numbers`为:`[1, 23, 456, 0]` ### 优化建议 1. **处理空值**:如果`codes`可能为`null`,则应该先判断: ```groovy if (codes == null) { codes = [] } ``` 2. **错误处理**:如果转换失败(例如匹配的数字字符串太大),可以捕获异常: ```groovy matcher.find() ? try { matcher.group().toInteger() } catch (Exception e) { 0 } : 0 ``` 但通常数字不大,可以不加。 3. **匹配所有数字**:如果需要匹配整个字符串中的所有数字,可以使用`matcher.findAll()`,然后选择需要的(比如最大值): ```groovy def allNumbers = matcher.findAll()*.toInteger() def maxInItem = allNumbers ? allNumbers.max() : 0 ``` ### 完整优化代码 ```groovy def numbers = codes.collect { item -> def matcher = (item.toString() =~ /\d+/) if (matcher.find()) { try { return matcher.group().toInteger() } catch (NumberFormatException e) { log.warn("数字转换失败: ${matcher.group()}", e) return 0 } } else { return 0 } } ``` §§相关问题§§1. 在Groovy中,如何提取字符串中的多个数字并分别处理?2. 当正则匹配失败时,除了返回0还有哪些错误处理方式?3. 如何修改正则表达式以匹配包含小数点的数字?4.JMeter的Groovy脚本中,如何安全地处理可能为空的集合?5. 如何优化正则表达式以提高匹配效率?</think>### 正则表达式提取优化方案 针对您提供的代码片段,存在几个关键问题需要优化: ```groovy def numbers = codes.collect { item -> (item =~ /\d+/).find() ? it[0] as Integer : 0 } ``` ### 问题分析 1. **变量引用错误**: - 使用了未定义的 `it` 变量(应为 `matcher.group()`) - `it[0]` 语法不适用于正则匹配结果 2. **类型安全缺失**: - 未处理非字符串元素(如 null 或数字类型) - 缺少数字转换异常处理 3. **正则匹配缺陷**: - `find()` 只返回布尔值,不包含匹配结果 - 未处理多数字匹配场景 ### 优化后的代码 ```groovy def numbers = codes.collect { item -> // 1. 安全类型转换 def str = item?.toString() ?: "" // 2. 创建正则匹配器 def matcher = (str =~ /\d+/) // 3. 提取第一个匹配的数字 if (matcher.find()) { try { // 获取匹配的完整数字字符串 return matcher.group().toInteger() } catch (NumberFormatException e) { log.warn("数字转换失败: ${matcher.group()}") return 0 } } else { // 4. 添加调试信息 log.debug("未找到数字: ${str}") return 0 } } ``` ### 关键优化点 1. **安全类型处理**: ```groovy // 使用安全导航操作符 ?. 和空值合并 ?: def str = item?.toString() ?: "" ``` 2. **正则匹配修复**: - 使用 `matcher.find()` 检查是否匹配 - 使用 `matcher.group()` 获取匹配内容 - 支持多数字匹配(返回第一个匹配项) 3. **异常处理增强**: ```groovy try { return matcher.group().toInteger() } catch (NumberFormatException e) { log.warn("数字转换失败: ${matcher.group()}") return 0 } ``` 4. **多数字场景处理**: ```groovy // 获取所有匹配数字 def allNumbers = matcher.findAll { it }*.toInteger() // 返回最大值(或根据需求调整) return allNumbers ? allNumbers.max() : 0 ``` ### 完整优化方案 ```groovy def numbers = codes.collect { item -> // 安全类型转换 def str = item?.toString()?.trim() ?: "" if (str.isEmpty()) { log.debug("空字符串跳过处理") return 0 } // 创建匹配器 def matcher = (str =~ /\d+/) // 提取所有匹配数字 def matches = matcher.findAll() if (matches) { try { // 转换为数字列表 def numList = matches.collect { it.toInteger() } // 根据需求选择返回值: // 1. 返回第一个数字 // return numList.first() // 2. 返回最大值 return numList.max() // 3. 返回最小值 // return numList.min() } catch (NumberFormatException e) { log.error("数字转换错误: ${matches} in '${str}'", e) return 0 } } else { log.debug("未找到数字: ${str}") return 0 } } ``` ### 使用示例 输入列表:`["test123", "dept-456", "section_789", null, 101]` 输出结果:`[123, 456, 789, 0, 101]` ### 调试建议 1. 添加详细日志: ```groovy log.info("原始数据: ${codes}") log.info("提取结果: ${numbers}") ``` 2. 使用 JMeter 调试取样器验证结果 3. 在 View Results Tree 中检查脚本执行日志
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值