处理 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如何测试websocket接口

JMeter基础 — 使用JMeter测试WebSocket接口

如何使用 JMeter 对 Websocket 进行负载测试?

jmeter websocket测试

JMeter怎样测试WebSocket

Jmeter进行webSocket接口测试