最近有一个微信聊天系统的项目须要性能测试,既然是测试微信聊天,确定绕不开websocket接口的测试,首选工具是Jmeter,网上能搜到现成的方法,可是网上提供的jar包每每不是最新的,既然是用最新版本的Jmeter4.0,那么所依赖的插件jar包也应该追求新的。因此提供了如下连接供你们下载(甚至连源码都提供):html
(1)Jmeter工具linux
(2)websocket请求模板 JMeterWebSocketSamplers web
(3)jetty-http正则表达式
(4)jetty-ioshell
(5)jetty-utilapache
(6)websocket-apiwindows
(7)websocket-client后端
(8)websocket-commonapi
将(2)~(4)中下载的jar包放到Jmeter如下目录下,就可以被调用了:浏览器
#将你下载的全部jar包,复制到
apache-jmeter-4.0\lib\ext
#该目录下
1、启动JMeter
windows环境打开 bin下的jmeter.bat
linux环境打开bin下的jmeter.sh
因为Jmeter4.0的界面是深色的(看不清字体),默认语言是英语,咱们能够调一下。先修改语言:在bin\jmeter.properties中找到#language=en,将前面的注释【#】去掉,改成language=zh_CN。这样启动后就是中文版的,而后到选项-->外观中选择Metal,这就变成传统Jmeter样式。
2、添加websocket Sampler
先在测试计划中添加线程组,而后右键添Sampler时就能看到websocket的模板:
经常使用的就是websocket request-response Sampler(链接+发送data或者只发data),其次是WebSocket Open Connection(只链接,不发送data)
配置举例以下:
说明:(1)Connection:有两项,第一项是使用已有链接,就是上一个websocket请求所创建的链接通道,选择后Server URL全置灰只读不可操做。第二项是新建链接通道。
(2)Server URL:能够发送ws协议和wss协议(加密的websocket),以上图的配置所对应的链接串以下:
ws://192.18.24.211:8888/testPath (这一点比旧版本的websocket插件配置要清晰明了)
(3)Data:支持文本(包括JSON)和Binary二进制数据的发送。默认请求响应的超时时间为6S,超过这个时间报错。(对于Data的文本格式最好是本身抓包获取,好比谷歌浏览器的F12开发者工具或Fiddler,不要太相信开发提供的接口文档)。
3、使用小技巧
一、Path和Requst data要注意编码格式
websocket发送数据到后端,与http请求的原理是相通的,因此发送的数据若是含有很是字符,如"/"、"+"、"%"、引号等,就会引发解析错误,因此须要特别注意,好比:
如上所示,websocket请求的上一个请求TR-token能够获取一个token串(经过正则表达式提取器提取),而这个串的格式多是这样的:Ivj6eZRx40+MTx2Zv/G8nA,能够发现含有"+"、"/"字符,而咱们须要把这个串做为Path的一部分来发送,那么咱们就须要对${token}变量进行URL转码,用到jmeter的函数 __urlencode()
二、能够经过逻辑控制器来模拟群发消息
(1)经过循环控制器调取参数化文件(CSV)里的用户信息表来实现群发消息,以下所示:
(2)或者先经过发送请求来获取用户信息(正则表达式提取),再用ForEach调取用户组变量发送消息,以下所示:
三、以时间戳来查看当前聊天记录应注意websocket的response延时
在并发的状况下,websocket请求延时可能要远大于http请求,好比延时2秒以上(从发送消息到看到聊天面板已通过了2秒以上)。因此在jmeter中用时间戳函数${__time(,)}来表示最新一条聊天记录的时间是不可靠的。咱们应该在websocket请求中插入正则表达式提取器,经过在response中获取其时间才能确保消息接收时间准确(即不要用客户端时间来判断你的聊天时间)。
(1)先提取websocket反馈的服务端时间戳
(2)再做为查询当前聊天记录的时间戳依据
四、最后说一下jmeter4.0,若是是要作分布式测试,jmeter4.0默认是要求RMI传输必须SSL加密的,不然jmeter-server就启动不了,咱们能够用简单的配置来回避这个问题。就是server端和client端的jmeter咱们统一作以下配置:
(1)用编辑器打开bin/user.properties文件
(2)找到server.rmi.ssl.disable,将#注释符去掉,改为 server.rmi.ssl.disable=true
如今能够奔跑了,我直接用如下shell脚本实如今linux下分布式调用jmeter-server进行测试,并生成html报告:
#!/bin/bash
testAPI="websocket-test.jmx" #jmeter测试脚本
Cur_Dir=$(cd "$(dirname "$0")"; pwd)
sed -i "s/csvData\\\/csvData\//g" $Cur_Dir/jmeter4.0/bin/${testAPI} #替换参数路径斜杠\为/
$Cur_Dir/jmeter4.0/bin/jmeter -n -t $Cur_Dir/jmeter4.0/bin/${testAPI} -R 172.16.1.67,172.16.5.241 -l $Cur_Dir/DashReport/log-$(date -d "today" +"%Y%m%d%H%M%S").csv -e -o $Cur_Dir/DashReport/htmlReport-$(date -d "today" +"%m%d%H%M%S")
另外测试还开启了jmeter监控工具(influxDB+grafana),具体安装配置方式参见个人另外一篇文章《关于Jmeter长时间压测的可视化监控报告》(区别是这篇文章用的是windows版的,而我此次测试用的是Linux版的,网上有相关下载,开源工具)。
添加配置后,监控后的效果以下:
补充:除了经常使用的WebSocket Open Connection和WebSocket request-response 这两个Sampler,WebSocket Single Read Sampler也比较经常使用,通常是用在群聊消息已读回执的发送。好比在微信群里发一条消息,经过抓包分析,能够看到客户端是发出了两条消息(同时服务端也回发了两条消息),以下所示:
第二条消息表示发送消息已读回执,按以往的方式,咱们须要经过正则表达式提取器提取第一条消息的返回值,而后发送第二条消息,这样的效率就不高,咱们能够直接用WebSocket Single Read Sampler来模拟消息的已读回执: