使用JMeter进行WebSocket负载测试时的线程和消息序列处理

使用JMeter进行WebSocket负载测试时的线程和消息序列处理,websocket,jmeter,jmeter-plugins,Websocket,Jmeter,Jmeter Plugins,首先,我对JMeter很陌生。 我正在尝试对websocket服务进行负载测试,但我还没有弄清楚如何在收到对前一条消息的响应后,在有限数量的并发连接中,在一个连接内顺序(而不是与其他线程并行)发送多条消息 我的连接也不会关闭,因为如果找到响应模式,则无法识别关闭模式 更新 修改WebSocketSampler代码后,消息特定的匹配模式和匹配与关闭都可以工作;代码最终会发生变化 本例的目标 打开总共12个连接(3个并发连接,在上一个连接关闭后打开新连接) 向每个连接发送5条消息 每条消息都包含

首先,我对JMeter很陌生。 我正在尝试对websocket服务进行负载测试,但我还没有弄清楚如何在收到对前一条消息的响应后,在有限数量的并发连接中,在一个连接内顺序(而不是与其他线程并行)发送多条消息

我的连接也不会关闭,因为如果找到响应模式,则无法识别关闭模式

更新 修改WebSocketSampler代码后,消息特定的匹配模式和匹配与关闭都可以工作;代码最终会发生变化

本例的目标
  • 打开总共12个连接(3个并发连接,在上一个连接关闭后打开新连接)
  • 向每个连接发送5条消息
    • 每条消息都包含格式为“messageIx”:n的键值对(其中n是1到5之间的整数)
    • 等待,直到收到包含相同密钥的第一个响应
    • 发送下一条消息
  • 当收到包含“messageIx”:5的响应时,关闭连接
实际应用程序将为每条消息发送多达4个响应。但即使使用WS-echo服务,我也无法找到一种方法来实现这一点。 我正在使用作为JMeter的插件

当前设置
  • 螺纹组
    • 3线程
    • 加速1秒
    • 循环计数5
  • 网袋取样器
    • 连接超时5000ms
    • 响应超时5000ms
    • 请求数据${Request}
    • 响应模式${Response}
    • 关闭连接模式\“messageIx\”:5
  • CSV数据集配置
    • 变量名请求、响应
    • 共享模式当前线程
    • 定界符
    • 在EOF上循环使用False
    • EOF上的停止线程:True
我的CSV文件内容:

 {"messageType":0,"messageIx":1,"action":"None"};"messageIx":1
 {"messageType":0,"messageIx":2,"action":"None"};"messageIx":2
 {"messageType":0,"messageIx":3,"action":"None"};"messageIx":3
 {"messageType":0,"messageIx":4,"action":"None"};"messageIx":4
 {"messageType":0,"messageIx":5,"action":"Close"};"messageIx":5
对SimpleWebSocketServer(python)实现输出运行此配置是非常困难的

 52682 :  connected
 52682 <--  {"messageType":0,"messageIx":1,"action":"None"}
 52691 :  connected
 52691 <--  {"messageType":0,"messageIx":1,"action":"None"}
 52700 :  connected
 52700 <--  {"messageType":0,"messageIx":1,"action":"None"}
 52682 <--  {"messageType":0,"messageIx":2,"action":"None"}
 52691 <--  {"messageType":0,"messageIx":2,"action":"None"}
 52700 <--  {"messageType":0,"messageIx":2,"action":"None"}
 52682 <--  {"messageType":0,"messageIx":3,"action":"None"}
 52691 <--  {"messageType":0,"messageIx":3,"action":"None"}
 52700 <--  {"messageType":0,"messageIx":3,"action":"None"}
 52682 <--  {"messageType":0,"messageIx":4,"action":"None"}
 52691 <--  {"messageType":0,"messageIx":4,"action":"None"}
 52700 <--  {"messageType":0,"messageIx":4,"action":"None"}
 52682 <--  {"messageType":0,"messageIx":5,"action":"Close"}
 52691 <--  {"messageType":0,"messageIx":5,"action":"Close"}
 52700 <--  {"messageType":0,"messageIx":5,"action":"Close"}
 52682 <--  <EOF>
 52691 <--  <EOF>
 52700 <--  <EOF>
 52682 <--  <EOF>
 52691 <--  <EOF>
 52700 <--  <EOF>
 52691 :  closed
 52682 :  closed
 52700 :  closed
但对于以下消息,没有匹配项

[Execution Flow]
 - Reusing exising connection
 - Waiting for messages for 5000 MILLISECONDS
 - Received message #2 (47 bytes); didn't match any pattern
 - Leaving streaming connection open
对于线程的最后一条消息,除了客户端关闭连接外,数据是相同的(但流连接保持打开状态)

但是,如果我将响应模式修改为泛型\“messageIx\”:所有消息都匹配,但关闭连接与\“messageIx\”:5或关闭模式都不匹配

Response data:
[Message 5]
{"messageType":0,"messageIx":5,"action":"Close"}

Sampler request:
[Execution Flow]
 - Reusing exising connection
 - Waiting for messages for 5000 MILLISECONDS
 - Received message #5 (48 bytes); matched response pattern
 - Leaving streaming connection open
最后,线程。如果我设置了12个线程,它们在开始时都会有上升延迟。 添加循环控制器只会增加同一连接的消息,增加线程组中的循环(并在csv读取器中使用循环)将失败,因为连接已经关闭(如果关闭连接模式匹配)

我在寻找帮助
  • 如何使用唯一的匹配模式匹配每条消息
  • 如何在找到匹配模式的同时关闭邮件
  • 我应该如何创建线程数量,每个线程都有新的连接,但将并发数量限制在较低的数量
  • 如果我在这里问了一些非常愚蠢的问题,请原谅,因为我对JMeter很陌生:)

    更新:修改的WebSocketSampler代码 从Sampler的GitHub页面中,我发现了类似于我的消息匹配问题的问题:

    我下载了1.0.2-SNAPSHOT源代码,添加了对上述问题的第二次回复的修改,并在ServiceSocket.java文件中更改了代码(第68行),如下所示:

    boolean matchFound = false;
    if (responseExpression == null || responseExpression.matcher(msg).find()) {
        logMessage.append("; matched response pattern");
        closeLatch.countDown();
        matchFound = true;
    }
    if (!disconnectPattern.isEmpty() && disconnectExpression.matcher(msg).find()) {
        logMessage.append("; matched connection close pattern").append("\n");
        closeLatch.countDown();
        matchFound = true;
        close(StatusCode.NORMAL, "JMeter closed session.");
    }
    
    if (!matchFound)
    {
        logMessage.append("; didn't match any pattern").append("\n");
    } else {
        logMessage.append("\n");
    }
    
    我以前从未编写过Java——如果我所应用的更改是合理的,我将非常感谢更有经验的人发表评论

    现在我可以单独匹配消息,也可以关闭连接。仍在寻找有关限制并发线程数量的帮助,而不必为消息重复使用相同的连接

    更新2:重新连接 限制并发用户数(连接数)的一种方法是使用CSV文件作为源,并将EOF上的recycle设置为true,将threads设置为并发目标,将loop count设置为每个线程的连接数乘以CSV文件中的消息数

    在1.0.2上,这不会直接起作用,因为connectionId不会改变,插件尝试使用旧的、封闭的连接。在WebSocketSamples.java上,第69行:

        if (isStreamingConnection()) {
             if (connectionList.containsKey(connectionId)) {
                 socket = connectionList.get(connectionId);
    
                 if (socket.isConnected()){
                    socket.initialize(this);
                    return socket;
                 } 
                 connectionList.remove(connectionId, socket);
             }
    
    修改似乎起到了作用。与基于Node.JS的Thor相比,消息似乎仍然是并行发送的,性能似乎相当差:(

    boolean matchFound = false;
    if (responseExpression == null || responseExpression.matcher(msg).find()) {
        logMessage.append("; matched response pattern");
        closeLatch.countDown();
        matchFound = true;
    }
    if (!disconnectPattern.isEmpty() && disconnectExpression.matcher(msg).find()) {
        logMessage.append("; matched connection close pattern").append("\n");
        closeLatch.countDown();
        matchFound = true;
        close(StatusCode.NORMAL, "JMeter closed session.");
    }
    
    if (!matchFound)
    {
        logMessage.append("; didn't match any pattern").append("\n");
    } else {
        logMessage.append("\n");
    }
    
        if (isStreamingConnection()) {
             if (connectionList.containsKey(connectionId)) {
                 socket = connectionList.get(connectionId);
    
                 if (socket.isConnected()){
                    socket.initialize(this);
                    return socket;
                 } 
                 connectionList.remove(connectionId, socket);
             }