GVKun编程网logo

jmeter下的websocket自动化与压力测试(jmeter websocket压测)

18

这篇文章主要围绕jmeter下的websocket自动化与压力测试和jmeterwebsocket压测展开,旨在为您提供一份详细的参考资料。我们将全面介绍jmeter下的websocket自动化与压力

这篇文章主要围绕jmeter下的websocket自动化与压力测试jmeter websocket压测展开,旨在为您提供一份详细的参考资料。我们将全面介绍jmeter下的websocket自动化与压力测试的优缺点,解答jmeter websocket压测的相关问题,同时也会为您带来(转)使用JMeter进行Web压力测试、javascript – 与Ruby和EM :: WebSocket :: Server的WebSocket握手、JMeter WebSocket 接口测试的最佳实践、JMeter WebSocket插件-关闭SignalR连接的实用方法。

本文目录一览:

jmeter下的websocket自动化与压力测试(jmeter websocket压测)

jmeter下的websocket自动化与压力测试(jmeter websocket压测)

最近新接手了个websocket项目,消息模式有点类似聊天室的操作。

没有办法确定response的内容和时间。在网上搜了一圈,也没有找到类似的科普文章。

在这里写一篇文章记录一下问题和解决情况。

希望能抛砖引玉,把这个问题攻克下来。

 

首先,准备jmeter环境和websocket的支持库。

相关操作在简书《JMeter测试WebSocket的经验总结》一文中可以找到。原文地址:

https://www.jianshu.com/p/bb8b3e928607

感谢 smooth00 大神的引用授权。

 

测试场景:

1.多名用户加入房间。

2.房间人数为固定人数(比如4人) 

3.有人进入时,进入用户会收到反馈当前房间人员列表。

4.其他人会收到反馈新加入用户的信息消息。

5.当人数已满时,会自动推送消息给所有人。

6.在人满后,每个人需要按固定序列,发送消息。

7.所有人发送特定消息后,推进房间状态,返回新的一组信息。

 

jmeter的逻辑结构

建立连接

循环1开始

  进入房间

  循环2开始

    接受消息

    解析消息

    if(消息格式符合条件1)

      执行动作1

    if(消息格式符合条件2)

      执行动作2

      设置循环2控制变量,跳出循环

    ...

  循环2结束

 循环1结束

 

 

在整个编辑过程中,踩了几个小坑。

1.用户自定义变量 不可修改

问题场景:在控制循环2的跳出条件时,直接使用了【用户自定义变量】来定义控制循环2的变量,结果,总是无法正确触发跳出循环。查询资料才知道【用户自定义变量】是会只读一次的类型。

解决方案:修改为【用户参数】,解决问题。

2.while循环和if判定的条件格式

问题场景:同样是用于条件格式,只有if强调了需要使用 __jexl3() 来计算语句逻辑,最终必须为true格式。

然后在实际使用中发现,while的判断也需要类似的需求。

最初填写的内容为  ${x}==a  ,此处由于  ${x} 不为 null 或false,就直接验证为成功了。

之后尝试修改 ${x}的值,仍然无法正确跳出循环,再加上问题1,导致浪费了很多时间。

解决方案:通过修改为 ${__jexl3(${notInRoom}==1,)},强制逻辑计算,解决手问题。

3.变量格式不一致,导致的判断异常

问题场景:同样是if判断,在判断中,由于字符变量的表现格式,在jmeter和java中的差异导致。

原本的判断类型为变量 stage 的值是否为字符串 settle。开始使用 ${__jexl3( ${stage} == settle,)},总是无法正确获取判断结果。

解决方案:修改两侧格式为字符串,${__jexl3( "${stage}" == "settle",)},解决问题。

4.固定定时器的延时状态会导致接受消息的时机被错过。

问题场景:原本为了放缓代码的刷新速度(调试阶段,太多了看不过来),在循环中添加了【固定定时器】延时。

结果在延时的过程中,经常会丢掉一些关键信息,导致本地逻辑无法继续。

解决方案:加长 response timeout的时长,代替延时

 

(转)使用JMeter进行Web压力测试

(转)使用JMeter进行Web压力测试

使用JMeter进行压力测试

说到压力测试,一般第一反应都是LoadRunner.这个软件也确实是自动化测试的一个事实标准.无奈这个软件太过庞大,以及不能在MacOS上使用.我由于项目的需要,需要对一个模块的WebServcie接口做压力的测试,于是就找到了另外一个神器JMeter. JMeter是Apache组织开发的基于Java的压力测试工具.它是由JAVA编写的,可以跨平台.最初只能测试Web应用,现在可以进行各种的压力测试,包括但不限于JAVA小程序,CGI脚本,JAVA RMI调用,数据库,FTP服务等等. 并且它的操作非常简单,通过几部的配置就可以创建一个完整的压力测试用例.

JMeter安装

JMeter是由JAVA编写的,所以需要依赖JDK的运行环境,最新版的JMeter需要JDK1.6以上的支持.

JMeter的软件可以通过官网下载.直接下载编译后的压缩包,然后在终端中输入:unzip apache-jmeter-2.13.zip进行解压

而后在终端中执行./jmeter即可启动主界面.

进行Web的压力测试

JMeter中最小的单位就是元件.你可以给你的测试计划中增加若干的元件,每一个元件其实就是一个步骤. JMeter中设置了各种不同的元件:有设置用户的,有设置定时器的,有设置前后置处理的,有设置断言的还有设置监听器的.通过这些不同的元件的组合,我们就能很很容易的组合出更多不同的压力测试用例.

我们以最简单的Web服务器的压力测试为例,来演示下如何使用JMeter设置测试用例.

设置线程组(模拟用户)

压力测试不同于功能测试,软件的正确性并不是它的测试重点。它所看重的是软件的执行效率,尤其是短时间内访问用户数爆炸性增长时软件的响应速度.因此就需要同时模拟多个用户对系统进行请求. 因此,一般设置测试计划的第一步都是创建一个线程组,用来模拟多个用户的操作.

 

 

 

而后就需要设置线程组的一些属性.

  • 线程数:相当于是模拟用户的数量.
  • 准备时长:表示线程之间间隔多少时间,单位是秒.0就表示了所有的线程并发发送请求,否则就是每个线程间隔几秒发送请求
  • 循环次数:表示每个线程执行几次
  • 调度器:就是创建线程的schedule.
  • 在取样器错误后执行的操作:表示线程出现错误后执行的操作.比如继续,或者停止线程,或者测试

 

 

 

设置HTTP请求

这里我们使用最简单的用例进行测试——访问我的博客的首页,测试QPS(Query Per Second 每秒查询率)的情况.

因此,接下来我们需要增加的就是在线程组上面右键—-添加—-Sampler—-HTTP请求.

 

 

 

在JMetaer中取样器(Sampler)就是与服务器进行交互的元件.一个取样器通常会进行三个部分的工作:

  • 向服务器发送请求
  • 记录服务器的响应数据
  • 记录响应的时间信息

 

 

这里我设置了:

  • 服务器名称: sunxiang0918.cn
  • 端口号: 80
  • HTTP请求实现: JAVA
  • 协议: http
  • 方法: GET
  • ContentEncoding: UTF-8
  • 路径: /

其实这样就算是完成了一个HTTP请求的设置了.这个时候我们就可以保存这个测试用例到一个JMX文件中.然后执行这个测试用例了. 不过,由于我们还没有配置监听器元件,因此,现在运行的话.我们是看不到任何的结果的.

请求参数模板化

在实际的使用中,我们的请求中可能有不同的参数,并且这些参数可能是不相同的.这就需要把参数模板化.

在JMeter中,参数的语法是: ${xxxx} 其中的xxxx即为参数名. 通过这个语法,就可以在整个请求中调用参数的值. 只要我们对这些参数进行赋值即可.

 

 

比如在这里我们增加一个Random Variable.这个表示的是随机的给一个变量进行赋值.

我们在这里设置了一个keyword的变量,其值为0100间的随机数.随机方式采用默认的.

 

 

然后在请求中增加一个请求的参数:

执行测试计划,会发现请求的URL就会变成:GET http://sunxiang0918.cn/?aaaaa=xxxx49,后面的数字就是随机.

除了随机变量或用户定义的变量外.还可以读取CSV文件,通过CSV Data Set Config,可以读取CSV文件,并且制定每一列的变量名是什么.这样就可以在请求的时候预设多个变量值.

增加响应断言

为了判断结果的正确性,我们有时需要增加响应的断言.比如响应代码必须是200才作数. JMeter中有一个元件就叫做响应断言.这个就可以加在HTTP请求的后面,用来判断结果是否正确.

 

 

 

在这里我只增加了一个最简单的通过响应代码来判断请求是否正确.

 

 

除此之外,它还能通过响应的内容,响应的头信息等来进行判断.功能非常的强大.

设置结果监听器

为了我们能查看到请求的结果,我们需要再添加监听器. 在这里我们增加三个结果监听器:察看结果树 图形结果以及聚合报告 查看结果树可以查看到每一次请求的具体情况,包括了请求参数,结果反馈,请求时间等等. 图形结果 可以以图形的方式展现请求的中和结果. 聚合报告会展示本次测试计划所有的请求的一个聚合的结果.

 

 

这几个结果监听器都不需要什么设置.增加后,即可再执行一次测试计划.里面就会有结果了.

 

 

我们先来看查看结果树. 它显示了这次请求的所有信息.比如开始时间,线程名字,完成用时,请求大小,反馈大小,反馈代码,采样次数,错误信息,反馈头信息,反馈体等等. 通过这个列表,我们就能很清楚的知道所有请求的大概情况.

 

 

然后就是图形结果 从这个图上就能很清楚的看出整个请求和响应的趋势.

 

 

最后就是聚合报告. 它用表格的形式展示了本次测试的总体情况.

LabelSamplesAverageMedian90%Line95%Line99%LineMinMaxErrorThroughputKB/sec名称采样请求数平均响应时间中位数90%用户响应时间95%用户响应时间99%用户响应时间最小响应时间最大响应时间错误请求百分比吞吐量,每秒完成请求数每秒接收数据量HTTP请求20081166015371886242227534240.00%15.8/sec542.3

限制QPS

为了了解博客的首页在负载达到30QPS时的响应时间,我们就需要控制向博客首页发送请求的负载为固定的30QPS. JMeter提供了一个非常有用的定时器:Constant Throughput Timer(常数吞吐量定时器),通过该定时器可以方便的控制给一个采样器发送请求的吞吐量.

 

 

 

 

 

 

首先是Target throughput目标吞吐量,需要注意的是这个的单位是分钟. 比如我们要测试的是30QPS,那么一分钟的吞吐量就是 1800. 而Calculate Throughput based on有五个选项:

  • This thread only:控制每一个线程的吞吐量.这个时候,总吞吐量就是Target throughput乘以线程数
  • All active threads:设置总体的吞吐量,它会把Target throughput分配到每一个活跃的想成上.
  • All active threads in current thread group.设置总体的吞吐量,它会把Target throughput分配到每一个活跃的想成上.当一个测试计划中只有一个测试组的时候,效果和All active threads是一样的.
  • All active threads(shared):与All active threads的区别在于,每个活跃线程都会在所有活跃线程上一次运行结束后等待一定的时间后再次运行.
  • All active threads in current thread group(shared):与All active threads in current thread group的区别在于,每个活跃线程都会在所有活跃线程上一次运行结束后等待一定的时间后再次运行.

因此,我们这里选择了All active threads.

需要注意的是:这个常量吞吐量定时器只有在线程组中产生了足够多的请求的时候才有意义.否则,就算设置了这个Target throughput,也有可能由于线程数和请求数不够,而打不到预期的目标.

在这个基础上再跑一次的结果为:

LabelSamplesAverageMedian90%Line95%Line99%LineMinMaxErrorThroughputKB/sec名称采样请求数平均响应时间中位数90%用户响应时间95%用户响应时间99%用户响应时间最小响应时间最大响应时间错误请求百分比吞吐量,每秒完成请求数每秒接收数据量HTTP请求30091072315251812326830592550.00%11.2/sec387.0

由此可见,在这里访问github.io,确实相当的慢啊….

总结

这里只是简单的展示了一下JMeter的用法,其实对其他的压力测试,比如WebService,Restful,RMI等的测试都可以参照这个步骤,增加不同的元件即可.

javascript – 与Ruby和EM :: WebSocket :: Server的WebSocket握手

javascript – 与Ruby和EM :: WebSocket :: Server的WebSocket握手

我正在尝试使用JavaScript在我的Rails应用程序中创建一个简单的WebSocket连接.我得到以下内容:

WebSocket connection to ‘ws://localhost:4000/’ Failed: Error during WebSocket handshake: ‘Sec-WebSocket-Accept’ header is missing

我究竟做错了什么?这是我的代码:

JavaScript的:

var socket = new WebSocket('ws://localhost:4000');

socket.onopen = function() {
  var handshake =
    "GET / HTTP/1.1\n" +
    "Host: localhost\n" +
    "Upgrade: websocket\n" +
    "Connection: Upgrade\n" +
    "Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\n" +
    "Sec-WebSocket-Protocol: quote\n" +
    "Sec-WebSocket-Version: 13\n" +
    "Origin: http://localhost\n";

  socket.send(handshake);
};

socket.onmessage = function(data) {
  console.log(data);
};

ruby:

require 'rubygems'
require 'em-websocket-server'

module QuoteService
  class WebSocket < EventMachine::WebSocket::Server
    def on_connect
      handshake_response =  "HTTP/1.1 101 Switching Protocols\n"
      handshake_response << "Upgrade: websocket\n"
      handshake_response << "Connection: Upgrade\n"
      handshake_response << "Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=\n"
      handshake_response << "Sec-WebSocket-Protocol: quote\n"

      send_message(handshake_response)
    end

    def on_receive(data)
      puts 'RECEIVED: ' + data
    end
  end
end

EventMachine.run do
  print 'Starting WebSocket server...'
  EventMachine.start_server '0.0.0.0', 4000, QuoteService::WebSocket
  puts 'running'
end

握手标头是每Wikipedia.

解决方法:

1)我认为一旦连接打开,请求和响应已经发生,所以在那时发送标题为时已晚.此外,标题必须以空行结束,您省略了该行.

2)根据演示,您甚至不必在客户端或服务器中设置标头 – ruby​​模块自动处理服务器端的标头,html5自动处理客户端的标头.我认为这应该有效:

require "em-websocket-server"

class EchoServer < EM::WebSocket::Server

  def on_connect
    EM::WebSocket::Log.debug "Connected"
    puts "I felt a connection."
  end

  def on_receive msg
    puts "RECEIVED: #{msg}"
    send_message msg
  end

end

EM.run do
  myhost = "0.0.0.0"
  myport = 8000
  puts "Starting WebSocket server.  Listening on port #{myport}..."
  EM.start_server myhost, myport, EchoServer
end  

html文件:

<!DOCTYPE html> <html> <head><title>Test</title>

<script type="text/javascript">

  var myWebSocket = new WebSocket("ws://localhost:8000");

  myWebSocket.onopen = function(evt)    { 
    console.log("Connection open. Sending message..."); 
    myWebSocket.send("Hello WebSockets!");       };

  myWebSocket.onmessage = function(evt)    { 
    console.log(evt.data);
    myWebSocket.close();   };

  myWebSocket.onclose = function(evt)    { 
    console.log("Connection closed.");    };

  myWebSocket.onerror = function(err)   {
    alert(err.name + " => " + err.message);   } </script>

</head> <body>   <div>Hello</div> </body> </html>

它确实在Safari 5.1.9(这是一个较旧的浏览器)中工作:我在服务器和客户端上都看到了预期的输出.但是,代码在Firefox 21中不起作用:我收到错误消息…

Firefox can't establish a connection to the server at ws://localhost:8000/.
    var myWebSocket = new WebSocket("ws://localhost:8000");

我注意到在Firebug和Safari Developer Tools中,服务器都没有发送Sec-WebSocket-Accept标头:

Response Headers

Connection          Upgrade
Upgrade         WebSocket
WebSocket-Location  ws://localhost:8000/
WebSocket-Origin    null


Request Headers

Accept                  text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding         gzip, deflate
Accept-Language         en-US,en;q=0.5
Cache-Control           no-cache
Connection          keep-alive, Upgrade
DNT                 1
Host                    localhost:8000
Origin                  null
Pragma                  no-cache
Sec-WebSocket-Key   r9xT+ywe533EHF09wxelkg==
Sec-WebSocket-Version   13
Upgrade                 websocket
User-Agent          Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:21.0) Gecko/20100101 Firefox/21.0

我试过的任何东西都不会使代码在Firefox 21.0中运行.要检查Firefox 21.0是否支持websockets,我去了:

http://www.websocket.org/echo.html  

它说我的浏览器确实支持websockets.

3)您是否有必要使用em-websocket-server模块? github上该模块的最后一次修改是在三年前.每当你在ruby代码中看到需要rubygems时,它应该提醒你代码是旧的.我尝试了更新的em-websocket模块,并且我能够使用Firefox 21.0和Safari 5.1.9上的websockets成功地来回传输数据:

require 'em-websocket'

myhost = "0.0.0.0"
myport = 8000

EM.run {
  puts "Listening on port #{myport}..."

  EM::WebSocket.run(:host => myhost, :port => myport, :debug => false) do |ws|

    ws.onopen do |handshake|
      path = handshake.path
      query_str = handshake.query
      origin = handshake.origin

      puts "WebSocket opened:"
      puts "\t path  \t\t -> #{path}" 
      puts "\t query_str \t -> #{query_str}"
      puts "\t origin \t -> #{origin}"
    end 

    ws.onmessage { |msg|
      ws.send "Pong: #{msg}"
    }
    ws.onclose {
      puts "WebSocket closed"
    }
    ws.onerror { |e|
      puts "Error: #{e.message}"
    }
  end
}

相同的客户端代码.现在响应头包括Sec-WebSocket-Accept:

Response Headers

Connection          Upgrade
Sec-WebSocket-Accept    LyIm6d+kAAqkcTR744tVK9HMepY=
Upgrade                 websocket


Request Headers

Accept  text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Cache-Control   no-cache
Connection  keep-alive, Upgrade
DNT 1
Host    localhost:8000
Origin  null
Pragma  no-cache
Sec-WebSocket-Key   pbK8lFHQAF+arl9tFvHn/Q==
Sec-WebSocket-Version   13
Upgrade websocket
User-Agent  Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:21.0) Gecko/20100101 Firefox/21.0

在您的代码中,我认为您没有设置任何标头.相反,您只是来回发送包含看起来像标题的字符的消息.显然,您的浏览器在允许连接之前需要响应中的Sec-WebSocket-Accept标头,并且当em-websocket-server模块未能在响应中设置该标头时,您的浏览器会拒绝连接.

em-websockets-server的相关源代码如下所示:

module EM
  module WebSocket
    module Protocol
      module Version76

        # generate protocol 76 compatible response headers
        def response
          response = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n"
          response << "Upgrade: WebSocket\r\n"
          response << "Connection: Upgrade\r\n"
          response << "Sec-WebSocket-Origin: #{origin}\r\n"
          response << "Sec-WebSocket-Location: #{scheme}://#{host}#{path}\r\n"

          if protocol
            response << "Sec-WebSocket-Protocol: #{protocol}\r\n"
          end

          response << "\r\n"
          response << Digest::MD5.digest(keyset)

          response
        end

如您所见,它没有设置Sec-WebSocket-Accept标头.该代码位于名为Version76的模块中,并且搜索google for websockets版本76会产生一个过时的协议(其中包含请求和响应的示例):

http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76

这是当前的websockets协议(其中还包含请求和响应的示例):

http://tools.ietf.org/html/rfc6455

结论:em-websockets-server已经过时了.

JMeter WebSocket 接口测试的最佳实践

JMeter WebSocket 接口测试的最佳实践

WebSocket: 实时双向通信的探索及利用 JMeter 进行应用性能测试

WebSocket 是一项使客户端与服务器之间可以进行双向通信的技术,适用于需要实时数据交换的应用。为了衡量和改进其性能,可以通过工具如 JMeter 进行测试,但需要先对其进行适配以支持 WebSocket。

配置 JMeter 以实验 WebSocket 应用

JMeter 本身并不内置支持 WebSocket 协议,因此,我们首先需要对其进行扩展。下面是如何安装必要插件的步骤:

  • 首先访问 JMeter 插件管理器官方下载页面,下载并安装 JMeter Plugins Manager
  • 通过 JMeter 插件管理器,搜索并安装 WebSocket Sampler,这是用于测试 WebSocket 服务的工具。

image.png

创建和配置测试脚本

一旦正确安装了 WebSocket Sampler 插件,我们可以开始创建一个测试脚本:

步骤 1: 新建线程组

JMeter 中,线程组允许你定义多个用户的模拟交互行为。

image.png

步骤 2: 添加 WebSocket Sampler

示例交互: 发送 "Hello"

image.png

在配置采样器以与特定 WebSocket 服务器通信时,设置如下:

  • 服务器名称或 IP 地址:websocket-echo.com
  • 启用流式连接选项
  • 请求数据填写为:“hello~”

示例交互: 发送 "Bye" 并关闭连接

image.png

进行第二次采样的设置包括:

  • 服务器名称或 IP 地址:websocket-echo.com
  • 启用流式连接选项
  • 请求数据填写为:“bye~”
  • 关闭连接的模式设置为触发“bye”关键词

步骤 3: 添加结果查看器

image.png

通过 View Result Tree 监听器查看测试结果,这有助于验证是否所有的交互都按预期进行。

执行和监控测试

配置完成后,运行 JMeter 测试脚本。通过结果查看器,我们可以详细审查每次交互的反馈,确认是否存在问题或瓶颈。

image.png

通过上述步骤,我们可以有效地设计和实施针对 WebSocket 服务的性能测试,确保应用程序可以承载预期的用户负载,同时也验证功能的正确实现。这是确保实时通信应用程序质量的重要做法。

JMeter WebSocket插件-关闭SignalR连接

JMeter WebSocket插件-关闭SignalR连接

我有一个网站使用Asp.NET Core SignalR从服务器动态加载数据。

我在此页面上使用JMeter进行功能测试。我使用1.2.1版中的WebSocket采样器插件来测试SignalR功能。

遵循有关如何将JMeter与WebSocket采样器插件一起使用的blazemeter教程之后,在尝试关闭SignalR连接时,总会出现错误。

我的JMeter采样器设置如下:

  1. WebSocket打开连接
  2. WebSocket请求-响应采样器
  3. WebSocket单读采样器
  4. WebSocket关闭

为了关闭连接,我使用称为的WebSocket采样器WebSocket Close。此采样器允许提供一个Close status

我尝试提供不同的Close status代码。但实际上未确认所有提供的代码,并且始终返回错误消息:

响应代码:WebSocket错误:关闭失败。

响应消息:WebSocket错误:收到的不是封闭框架,而是包含文本的文本框架…

如何在JMeter中正确关闭此连接?


更新资料

我发现这取决于我使用多少个采样器。如果我在读采样器之前使用写采样器,则关闭似乎有效。喜欢:

  1. WebSocket打开连接
  2. WebSocket请求-响应采样器
  3. WebSocket单读采样器
  4. WebSocket单写采样器
  5. WebSocket关闭

但是,如果我想拥有一个以上的读取采样器,它将不起作用。知道如何正确使用多重读取采样器吗?


更新2

我已经阅读了插件文档,并在此处检查了示例JMeter文件。不幸的是,到目前为止,我还没有找到具有多个Read
Samplers的更大样本。

关于jmeter下的websocket自动化与压力测试jmeter websocket压测的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于(转)使用JMeter进行Web压力测试、javascript – 与Ruby和EM :: WebSocket :: Server的WebSocket握手、JMeter WebSocket 接口测试的最佳实践、JMeter WebSocket插件-关闭SignalR连接等相关知识的信息别忘了在本站进行查找喔。

本文标签: