最近有一個微信聊天系統的項目需要性能測試,既然是測試微信聊天,肯定繞不開websocket接口的測試,首選工具是Jmeter,網上能搜到現成的方法,但是網上提供的jar包往往不是最新的,既然是用最新版本的Jmeter4.0,那麼所依賴的插件jar包也應該追求新的。是以提供了以下連結供大家下載下傳(甚至連源碼都提供):
(1)
Jmeter工具 (2) websocket請求模闆 JMeterWebSocketSamplers (3) jetty-http (4) jetty-io (5) jetty-util (6) websocket-api (7) websocket-client (8) websocket-common 将(2)~(4)中下載下傳的jar包放到Jmeter以下目錄下,就能夠被調用了:#将你下載下傳的所有jar包,複制到
apache-jmeter-4.0\lib\ext
#該目錄下
一、啟動JMeter
windows環境打開 bin下的jmeter.bat
linux環境打開bin下的jmeter.sh
由于Jmeter4.0的界面是深色的(看不清字型),預設語言是英語,我們可以調一下。先修改語言:在bin\jmeter.properties中找到#language=en,将前面的注釋【#】去掉,改為language=zh_CN。這樣啟動後就是中文版的,然後到選項-->外觀中選擇Metal,這就變成傳統Jmeter樣式。
二、添加websocket Sampler
先在測試計劃中添加線程組,然後右鍵添Sampler時就能看到websocket的模闆:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAnYld3LcRXYtJ3bm9CX3QjMvw1dvwlMvwlM3VWaWV2Zh1WaDdTJwlmc0N3LcRnbllmcv1yb0VXYvwlMyd2bNV2Zh1Wa-cmbw5SZxMmZzEDMkljN4IjMwQGNtADMzYTNwITMvw1cldWYtl2XkF2bsBXdvw1bp5SdoNnbhlmauMXZnFWbp1CZh9GbwV3Lc9CX6MHc0RHaiojIsJye.png)
常用的就是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,不要太相信開發提供的接口文檔)。
三、使用小技巧
1、Path和Requst data要注意編碼格式
websocket發送資料到後端,與http請求的原理是相通的,是以發送的資料如果含有非常字元,如"/"、"+"、"%"、引号等,就會引起解析錯誤,是以需要特别注意,比如:
如上所示,websocket請求的上一個請求TR-token可以擷取一個token串(通過正規表達式提取器提取),而這個串的格式可能是這樣的:Ivj6eZRx40+MTx2Zv/G8nA,可以發現含有"+"、"/"字元,而我們需要把這個串作為Path的一部分來發送,那麼我們就需要對${token}變量進行URL轉碼,用到jmeter的函數 __urlencode()
2、可以通過邏輯控制器來模拟群發消息
(1)通過循環控制器調取參數化檔案(CSV)裡的使用者資訊表來實作群發消息,如下所示:
(2)或者先通過發送請求來擷取使用者資訊(正規表達式提取),再用ForEach調取使用者組變量發送消息,如下所示:
3、以時間戳來檢視目前聊天記錄應注意websocket的response延時
在并發的情況下,websocket請求延時可能要遠大于http請求,比如延時2秒以上(從發送消息到看到聊天面闆已經過了2秒以上)。是以在jmeter中用時間戳函數${__time(,)}來表示最新一條聊天記錄的時間是不可靠的。我們應該在websocket請求中插入正規表達式提取器,通過在response中擷取其時間才能確定消息接收時間準确(即不要用用戶端時間來判斷你的聊天時間)。
(1)先提取websocket回報的服務端時間戳
(2)再作為查詢目前聊天記錄的時間戳依據
4、最後說一下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來模拟消息的已讀回執:
為了避免這條已讀回執消息偶爾出現逾時報錯,我們可以将Optional read勾選。