MQTT全名為Message Queuing Telemetry Transport,是一種基于TCP/IP協定上傳輸的輕量級通信協定。MQTT協定是一種消息隊列傳輸協定,采用訂閱、釋出機制,訂閱者隻接受自己已經訂閱的資料,非訂閱資料則不接受,既保證了必要的資料交換,又避免了無效資料造成的存儲與處理。是以在工業物聯網中得到廣泛的應用。
作者:張鵬飛
機關:中移物聯有限公司
Part 01
● MQTT協定 ●
MQTT協定是物聯網平台的最通用協定之一,也是OneNET平台的首要裝置接入協定。物聯網平台必須海量裝置接入,但MQTT接入服務究竟能同時支援多少裝置同時線上呢?了解這個名額能更好地為平台的運維和營運提供科學的依據。
可是,如何快速簡便地測試最大線上量名額呢?如何選取工具和制作腳本呢?
測試性能我們首先想到的是常用的Jmeter和Locust等性能測試工具。但是這些工具的優勢在測試服務的并發和吞吐量,并不适合目前的測試場景。
然後能想到的是利用第三方Jar包或者三方庫實作的協定庫,采用多線程啟動裝置。但是壓力機線程啟動有限,對動則支援幾十萬上百萬裝置接入量的服務簡直就是杯水車薪,需要多少壓力機難以估量。
再次能想到的是Select方法批量管理裝置的Socket連接配接。問題又出現了,Select管理的異步IO也是有極限的,此方法最終還是放棄。
Part 02
● 測試方法 ●
經過前面的分析、實踐最終方法确定,采用異步IO的方式批量模拟裝置連接配接伺服器,按照一定的頻率上報注冊封包,不斷周遊裝置Socket接收的緩存資料,解析服務消息來判斷裝置是否連接配接成功,并通過周期性上報心跳來保持裝置持續線上。實作細節如下:
(1)實作基礎裝置類:封裝部分MQTT協定封包方法,其中包括裝置注冊、訂閱、釋出、心跳等。
MQTT注冊封包封裝示例(Java)
(2)實作裝置類:主要記錄裝置注冊狀态、訂閱狀态、保活間隔,最重要的服務消息的解析和響應方法,以及裝置連接配接伺服器的非阻塞Socket(Java中的SocketChanel)
服務消息解析代碼示例(Java)
(3)實作程式主體類:管理批量裝置,控制裝置注冊頻率,裝置何時上報資料、監聽服務下發資料,統計裝置連接配接數,持續上報心跳,保持裝置線上等。具體實作邏輯如下:
- 批量初始化裝置清單;
- 同時啟動一下三個線程;
- 啟動裝置注冊線程,初始化裝置與服務連接配接并上行注冊封包,可根據設定,指定目前可同時注冊的裝置數,所有裝置注冊完成後自動退出;
- 啟動連接配接統計線程,周期性統計裝置連接配接成功個數、訂閱成功個數、連接配接失敗裝置等資料;
- 啟動裝置Socket周遊線程,持續輪詢每個Socket的接收資料,對接收到的資料處理和響應,每輪周遊完畢對需要對未長時間未上報心跳的裝置上行心跳封包,以達到裝置保活的目的。
程式主題類接收線程邏輯代碼片段(Java)
完成程式代碼後,測試工具制作完成。
此工具已實際用于項目性能測試中,可将壓力機全部可用端口用于最大裝置線上量的測試中,實際在Linux虛拟機中幾分鐘内完成50000+裝置注冊,并保持裝置長時間持續線上。
此工具能最大限度利用壓力機端口資源,提升測試執行效率,對于線上量較大的服務,隻需要在更多的壓力機上運作此工具即可。