JMeter測試WebSocket的經驗總結
最近有一個微信聊天系統的項目需要性能測試,既然是測試微信聊天,肯定繞不開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.0libext
#該目錄下
一、啟動JMeter
windows環境打開 bin下的jmeter.bat
linux環境打開bin下的jmeter.sh
由於Jmeter4.0的界面是深色的(看不清字體),默認語言是英語,我們可以調一下。先修改語言:在binjmeter.properties中找到#language=en,將前面的注釋【#】去掉,改為language=zh_CN。這樣啟動後就是中文版的,然後到選項-->外觀中選擇Metal,這就變成傳統Jmeter樣式。
二、添加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,不要太相信開發提供的介面文檔)。
三、使用小技巧
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勾選。
※Collection介面和List介面
※callback Promise async await 非同步回調 案例
TAG:程序員小新人學習 |