背景資訊
MQTT 是專為移動網際網路(Mobile Internet)、物聯網(IoT)設計的超輕量級消息協定,連接配接移動端與雲服務雙向通信,廣泛應用于各種應用領域,如端向雲彙報狀态、雲向端推送消息、端向端發送消息(即時聊天)等場景。MQTT 服務性能名額包括支撐同時線上移動端裝置數量、消息收發量級、消息延遲等。
可使用 JMeter + MQTT 插件進行 MQTT 壓測。
前提條件
- 已部署可在公網通路的 MQTT 服務。
- 已安裝 JMeter 5.x 版本。
安裝 MQTT 插件
- 下載下傳 mqtt-jmeter 插件最新版本 JAR 包: mqtt-xmeter-1.0.1-jar-with-dependencies.jar 。
- 拷貝插件 JAR 包到 JMeter 安裝目錄的
子目錄下。lib/ext/
cp mqtt-xmeter-1.0.1-jar-with-dependencies.jar "${JMETER_HOME:?}"/lib/ext/
準備用戶端資訊 CSV 檔案
每個 MQTT 用戶端需要提供如下資訊:
- 使用者名和密碼。
為保證安全,MQTT 伺服器通常需要認證,最常用的認證方式即使用者名和密碼認證。
- 用戶端 ID(ClientId)。
全局唯一 ID,唯一辨別一個用戶端,通常與使用者裝置關聯。如關聯手機序列号,則可通過用戶端 ID 變化檢測使用者是否更換了新手機。每個使用者可能有一個或多個用戶端 ID 。
壓測前需要預先準備好測試使用者和用戶端 ID 資料,儲存為 CSV 檔案供 JMeter 腳本使用。CSV 檔案應包含 userName 、 password 、 clientId 這 3 列資料。如期望壓測 10000 台用戶端裝置同時線上,則需要準備 10000 條用戶端資訊。
如用戶端資訊示例 CSV 檔案
client.csv
内容如下:
userName,password,clientId
pts_test,pts-pass1,client-test0001
pts_test,pts-pass1,client-test0002
pts_test,pts-pass1,client-test0003
最佳實踐:
- 使用測試使用者做性能測試,避免洩露真實使用者資訊,避免真實使用者産生髒資料。
- 使用預先準備的測試用戶端 ID 友善伺服器做用戶端 ID 校驗,同時友善跟蹤排查問題。
- 手工編輯 CSV 檔案很容易出錯,推薦使用 EXECL、Numbers 等軟體導出,或使用 Apache commons-csv 程式生成。
本地編輯 JMeter 腳本
本文操作以 JMeter 5.x 英文圖形界面為例。打開 選項/Options 菜單,選擇 語言/Choose Language > 英語/English 可切換到英文圖形界面。
讀取用戶端 CSV 資料檔案。
打開 JMeter,建立腳本。右鍵單擊 Test Plan ,選擇 Add > Threads (Users) > Thread Group 。右鍵單擊 Test Plan ,選擇 Add > Listener > View Results Tree ,添加 View Results Tree 監聽器,友善本地調試測試腳本。
JMeter 中一個線程模拟一個 MQTT 用戶端裝置,使用 Once Only Controller 保證一個線程僅讀取一次用戶端 CSV 資料檔案,綁定一條用戶端資訊。
- 右鍵單擊 Thread Group ,選擇 Add > Logic Controller > Once Only Controller 。
- 右鍵單擊 Once Only Controller , 選擇 Add > Config Element > CSV Data Set Config 。
配置 CSV Data Set Config 如下:

- Filename 輸入用戶端資訊 CSV 檔案名
注意:隻輸入檔案名client.csv
,不要包含(寫死)檔案路徑,以實作最大的通用性(可移植性),client.csv
同時請将
client.csv
檔案儲存到 JMeter 程序啟動目錄以保證能夠被讀取到。
- File encoding 設定 CSV 檔案編碼,這裡使用
UTF-8
- Recycle on EOF 選擇
。一條用戶端資訊隻能被讀取使用一次(與一個線程綁定),不允許循環讀檔案。False
建立 MQTT 連接配接
同樣使用 Once Only Controller 控制一個用戶端(對應一個線程)隻需執行一次建連操作。右鍵單擊 Once Only Controller,選擇 Add > Sampler > MQTT Connect ,配置如下:
MQTT 連接配接配置:
- Server name or IP 填寫 MQTT 伺服器公網位址。用戶端裝置通常使用公網通路 MQTT 服務。
- Port number MQTT 伺服器端口。填寫
,即使用标準 TCP 端口。1883
- MQTT version 選擇 MQTT 版本。選擇
,目前主流 MQTT 伺服器都支援3.1.1
版本。3.1.1
- Timeout(s) 逾時秒數填寫,即用戶端建立連接配接、發送消息等相關操作的逾時時間。填寫
,可按需調整。10
- Protocols 連接配接協定。選擇
,即使用标準 TCP 連接配接協定。TCP
MQTT 用戶端配置:
- User name 從 CSV 檔案讀取 userName 字段,填寫
${userName}
- Password 填寫
${password}
- ClientId 填寫
${clientId}
- 取消勾選 Add random suffix for ClientId 。本例使用預先準備好的固定用戶端 ID,不要添加字尾。
- Keep alive(s) 活動心跳間隔秒數。填寫
,連接配接空閑時,每 5 分鐘發送一次活動心跳,可按需調整。300
釋出消息
右鍵單擊 Thread Group,選擇 Add > Sampler > MQTT Pub Sampler ,配置如下:
- QoS Level 用戶端向伺服器釋出消息的服務品質。選擇 ,即隻發送一次,丢失不重發,可按需選擇其他級别。
- Topic name 填寫消息 topic 。MQTT topic 支援層次結構,使用
分割,類似檔案路徑,如/
等,這裡簡單使用pts_test/jmeter
做測試。pts_test
- 勾選 Add timestamp in payload ,消息頭添加發送時間戳,友善測試時檢查消息延遲。
- Payloads 消息體填寫
,這裡在消息體中添加用戶端 ID,友善測試和調試檢查。Aliyun PTS From ${clientId}
訂閱接收消息
右鍵單擊 Thread Group,選擇 Add > Sampler > MQTT Sub Sampler ,配置如下:
- QoS Level 伺服器向用戶端推送消息的服務品質。選擇
- Topic name 填寫消息 topic 。應與釋出消息的 topic 比對,如本例中為
pts_test
- 勾選 Payload includes timestamp,與發送消息時添加時間戳對應,接收消息後從消息頭解析出發送時間,進而計算出消息延遲,即從釋出端、途經伺服器、最後到達訂閱端花費的總時間。
- Sample on 選擇 specified elapsed time (ms),值填寫
1000
,表示持續接收消息 1000 毫秒。
這段時間内,可能一條消息都接收不到,也可能接收到多條消息。
- 勾選 Debug response,記錄接收到的消息内容,友善調試排查問題。正式執行性能測試時可取消該選項以優化性能和減少記憶體占用。
嘗試執行腳本。點選 Thread Group,配置 Loop Count 為
3
(循環執行 3 次)。儲存并執行腳本,結果如下。
添加消息訂閱線程組
目前腳本配置下,執行一次消息訂閱可能未收到消息但仍記錄為 1 次結果,可能收到多個消息但不能拆分記錄消息延遲,導緻壓測統計資料不準确。為了解決此問題,MQTT Sub Sampler 支援另一種工作模式:每收到一條消息産生一個有效的執行結果,這樣将更合理。但這種模式下,沒有收到消息時線程将一直阻塞,為了避免阻塞整個線程,應将訂閱消息拆分到不同的線程組。
釋出消息線程組移除訂閱操作後,應添加等待時間避免單個用戶端釋出消息過快。實際場景通常是用戶端數量多,但每個用戶端的消息量少。右鍵單擊 MQTT Pub Sampler ,選擇 Add > Time > Constant Timer,設定延時 1000 毫秒,即每次釋出消息後等待 1 秒。
建立消息訂閱線程組,從消息釋出線程組複制讀取 CSV 和 MQTT 連接配接配置,共享 CSV 檔案。此時一個用戶端(對應一條 CSV 記錄)要麼用于釋出消息,要麼用于訂閱消息,不能兩者同時使用。MQTT Sub Sampler 配置 Sample on 選擇 number of received messages,值設為
1
,即每收到一條消息産生一條執行結果。
測試執行腳本結果如下:
阿裡雲 PTS 壓測 MQTT 消息
在 PTS 控制台
建立 JMeter 壓測場景,上傳 mqtt-jmeter 插件 JAR 包、JMeter 腳本和用戶端資訊 CSV 檔案。用戶端資訊 CSV 檔案勾選 切分檔案 。高并發壓測時,阿裡雲 PTS 自動根據總并發數配置設定多台 JMeter 施壓機,勾選切分檔案保證一條用戶端資料隻能被一台施壓機上的一個線程使用。
在施壓配置頁,設定并發數和壓測時間。
注意:
- 每個線程使用一條用戶端資訊,總并發數不能大于 CSV 檔案提供的用戶端資訊條數。
- 腳本包含兩個線程組,這裡設定的是總并發數,運作時線程組并發數按原腳本設定并發數的比例配置設定。如原腳本兩個線程組并發均為 1,設定場景總并發為 10,則運作時兩個線程組并發各為 5 。若原腳本修改釋出消息并發數為 2,訂閱消息并發數為 1,設定場景總并發為 12,則運作時釋出消息并發為 8,訂閱消息并發為 4 。
點選 儲存去壓測,即可開始壓測,壓測過程中可看到實時并發數(釋出消息用戶端和訂閱消息用戶端總數),TPS 和 RT(消息延遲)等統計資訊。
本示例中釋出消息為廣播,每個消息訂閱用戶端都收到一份消息,總共有 5 個訂閱用戶端,是以可看到接收消息數是釋出消息數的 5 倍。
壓測結束後将生成壓測報告,可檢視場景并發、TPS、響應時間等變化趨勢圖和統計資料彙總等資訊。如果出現錯誤,還可以結合請求采樣日志和 JMeter 日志等進行排查。
已知問題:
- 釋出消息包含中文字元時,檢視接收到的消息包含亂碼。這是因為 MQTT 消息體為二進制資料,釋出消息時字元串使用系統編碼(UTF-8 或 GBK)轉為二進制,接收消息時預設使用 ISO-8859-1 将二進制轉為字元串,兩邊編碼不一緻導緻亂碼。