处理 JMeter WebSocket Sampler 的响应
Posted
技术标签:
【中文标题】处理 JMeter WebSocket Sampler 的响应【英文标题】:Processing JMeter WebSocket Sampler's response 【发布时间】:2018-09-11 07:25:57 【问题描述】:我是编程新手,有必要编写程序来使用 JMeter 进行负载测试,因为我找不到现有的 GUI 工具来执行我想做的事情。
我正在尝试使用 JMeter 插件“JMeter WebSocket Sampler”对 WebSocket 应用程序进行负载测试。
我需要建议我应该如何处理从 WebSocket 服务器发送的消息。
这里有一些条件。
-
与WebSocket服务器建立连接后,服务器在任意时间发送JMeter消息。
当JMeter收到消息时,它必须返回消息以通知消息已收到。
根据来自服务器的消息内容,JMeter 必须修改局部变量。
这是我当前的 JMeter 配置概览。
使用Parallel Controller划分线程接收消息和发送消息。
在接收消息线程中,我尝试在空WebSocket采样器下使用JSR223 Listner编写javascript来处理接收到的数据。服务器以 JSON 格式发送数据。
在发送消息线程时,我使用 While Loop 控制器,在接收消息线程时,它会等待直到变量值被更改,基于服务器的消息。
例如,当服务器向 JMeter 发送消息“Event_A_Notify”时,接收消息线程检查并将 Event 变量设置为“A”。然后,发送消息线程将向服务器发送“Event_A_Received”。
我遇到的问题是如何处理收到的消息。
在 JSR223 Lisner 中,我可以使用sampleResult.getResponseDataAsString() 方法从 WebSocket 服务器以字符串格式检索消息。
这是数据的样子。 (我修改了内容,使其看起来简单。实际消息内容更大,属性更多)。
[Message 1]
"Sample1":"A","uuid":"a5c77959-0284-40eb-9523-8706c947b620"
[Message 2]
"Sample2":"B","uuid":"93330fff-13fe-4040-9fe7-0e6d7054ee4a"
[Message 3]
"Sample3":"C","uuid":"099cea81-6f8f-4417-b0c5-29199f42a6f3"
[Message 4]
"Sample4":"D","uuid":"01bf3c23-87cb-41cb-ab04-1a9613a508a1"
当接收到的消息超过 10 条时,JMeter 会移除较旧的消息以保留 10 条最近的消息。
[Message 8]
"Sample8":"H","uuid":"01bf3c23-87cb-41cb-ab04-1a9613a508a1"
[Message 9]
"Sample9":"I","uuid":"01bf3c23-87cb-41cb-ab04-1a9613a508a2"
[Message 10]
"Sample10":"J","uuid":"01bf3c23-87cb-41cb-ab04-1a9613a508a3"
[Message 11]
"Sample11":"K","uuid":"01bf3c23-87cb-41cb-ab04-1a9613a508a4"
[Message 12]
"Sample12":"L","uuid":"01bf3c23-87cb-41cb-ab04-1a9613a508a5"
[Message 13]
"Sample13":"M","uuid":"01bf3c23-87cb-41cb-ab04-1a9613a508a6"
[Message 14]
"Sample14":"N","uuid":"01bf3c23-87cb-41cb-ab04-1a9613a508a7"
[Message 15]
"Sample15":"O","uuid":"01bf3c23-87cb-41cb-ab04-1a9613a508a8"
[Message 16]
"Sample16":"P","uuid":"01bf3c23-87cb-41cb-ab04-1a9613a508a9"
[Message 17]
"Sample17":"Q","uuid":"01bf3c23-87cb-41cb-ab04-1a9613a50810"
这里是JSR223 Listner 处理接收到的消息的内容。
基本上,我会做以下事情。
-
使用 sampleResult.getResponseDataAsString(); 检索响应。
使用 String(responseData).split(/[Message [0-9]+]/); 并通过删除 [Message \d] 将字符串拆分为消息数组。李>
使用数组对象 messageArray 存储来自 WebSocket 服务器的所有响应。并在for循环中一一处理。
var responseData = sampleResult.getResponseDataAsString(); var counter = parseInt(vars.get("counter1")); var messageList = new String(responseData).split(/\[Message [0-9]+\]/); messageList.shift(); var messageArray = vars.getObject("messageArray"); messageList.forEach(function(message, index) if (messageArray.indexOf(message) >= 0) return true; else messageArray.push(message); ); for (i = counter; i < messageArray.length; i++) if (messageArray[i].match(/(someEvent).*/)) vars.put("userVariable",true); counter += 1; break; else vars.put("userVariable",false); counter += 1; vars.put("counter1",counter); vars.putObject("messageArray", messageArray);
这段代码的问题是:
-
由于messageArray对象存储了所有的消息,messageArray变得太大,JMeter最终会因为OutOfMemory异常而崩溃。
检查接收到的消息是否存在于messageArray中的代码太慢,随着存储的消息数量的增加,性能呈指数级下降。
有人可以推荐一种更高效、更智能的方式来处理 JMeter 中的 WebSocket 消息吗?
非常感谢您的意见。
谢谢,
最好的问候,
【问题讨论】:
【参考方案1】:与 WebSocket 服务器建立连接后,服务器发送 任意时间的 JMeter 消息。当 JMeter 收到一个 消息,它必须返回消息以通知消息已收到。 根据来自服务器的消息内容,JMeter 必须修改 局部变量。
使用这个插件很容易实现:https://bitbucket.org/pjtr/jmeter-websocket-samplers/src/master/。 它提供了一个“读取采样器”,您可以使用它来等待消息,而不是从收到的消息中提取您需要的任何内容,然后使用“写入采样器”将消息返回给服务器。
【讨论】:
嗨彼得,感谢您的评论。这种方法的问题是我的环境需要与 2 个 WebSocket 服务器通信,并且“读取采样器”每个线程只能使用 1 个连接。所以我使用“WebSocket Sampler”,它允许每个线程有多个 WebSocket 连接。 嗨,Ken,似乎你已经解决了它......我仍然想补充一点,对多连接的支持正在开发中,虽然它还没有完全完成,但它应该可以工作.只需检查 bitbucket.org/pjtr/jmeter-websocket-samplers/branch/… 分支。如果您在使用此分支时遇到问题,只需在 git 存储库中提交问题,我会调查它。【参考方案2】:这是我想出的。
基本上遵循是我决定做的事情,现在似乎工作得更好。
提取消息索引和内容,然后分配给 JavaScript 对象的键值对。
处理完消息后,从 JavaScript 对象中删除消息索引和消息内容。
用于跟踪最近处理的消息索引的用户计数器变量。
// Retrieve response data from websocket server var responseData = sampleResult.getResponseDataAsString(); // Retrieve counter var counter = parseInt(vars.get("counter")); // Store index of message in to array meessageIndexArray var re = new RegExp(/\[Message ([0-9]+)\]/g); var messageIndex = [] var match; while (match = re.exec(responseData)) messageIndex.push(parseInt(match[1])); // Get the message List and remove [Message \d] field and new line. var messageList = new String(responseData).split(/\[Message [0-9]+\]/); messageList.shift(); // If counter value is less than the minimum number of the messageIndex, // set the counter to messageIndex[0] if (counter < messageIndex[0]) counter = messageIndex[0]; // Figure out the index of the counter value in the messageIndex var counterIndex = messageIndex.indexOf(counter); // Put all of the messages into messageObject object with messageIndex as a key and messageList as a value var messageObject = vars.getObject("messageObject"); if (counterIndex != -1) for (i = counterIndex; i < messageIndex.length; i ++) messageObject[messageIndex[i]] = messageList[i]; // Iterate through messageObject properties to check message for (var prop in messageObject) if (messageObject[prop].match(/(SomeValue).*/)) vars.put("userVariable",value1); .. delete messageObject[prop]; counter += 1; break; else vars.put("userVariable",value2); delete messageObject[prop]; counter += 1; vars.put("counter",counter); vars.putObject("messageObject", messageObject);
【讨论】:
以上是关于处理 JMeter WebSocket Sampler 的响应的主要内容,如果未能解决你的问题,请参考以下文章
JMeter基础 — 使用JMeter测试WebSocket接口