MQTT全名為Message Queuing Telemetry Transport,是一種基于TCP/IP協議上傳輸的輕量級通信協議。MQTT協議是一種消息隊列傳輸協議,采用訂閱、發布機制,訂閱者只接受自己已經訂閱的數據,非訂閱數據則不接受,既保證了必要的數據交換,又避免了無效數據造成的存儲與處理。因此在工業物聯網中得到廣泛的應用。
MQTT協議(yi)(yi)是(shi)物聯網平臺(tai)的(de)(de)(de)最(zui)通用協議(yi)(yi)之一,也是(shi)OneNET平臺(tai)的(de)(de)(de)首要設備接入(ru)協議(yi)(yi)。物聯網平臺(tai)必(bi)須海量設備接入(ru),但MQTT接入(ru)服務究竟能同(tong)時支持多(duo)少設備同(tong)時在(zai)線呢?了(le)解這(zhe)個(ge)指標能更好(hao)地為(wei)平臺(tai)的(de)(de)(de)運(yun)維和運(yun)營提供科學的(de)(de)(de)依據。
可是,如(ru)何(he)快速簡便(bian)地測(ce)試最大在(zai)線(xian)量(liang)指標(biao)呢(ni)?如(ru)何(he)選取工具和制作腳(jiao)本呢(ni)?
測(ce)試(shi)性能我們首先想到的(de)是常用的(de)Jmeter和Locust等性能測(ce)試(shi)工具(ju)。但是這些工具(ju)的(de)優勢在(zai)測(ce)試(shi)服務的(de)并(bing)發和吞(tun)吐(tu)量,并(bing)不(bu)適合當(dang)前的(de)測(ce)試(shi)場景。
然后能想到的(de)(de)是利用第三(san)方Jar包(bao)或者(zhe)三(san)方庫(ku)實現(xian)的(de)(de)協(xie)議庫(ku),采用多線(xian)程(cheng)啟動(dong)設備(bei)。但是壓(ya)力(li)機線(xian)程(cheng)啟動(dong)有限,對動(dong)則支持幾十萬上百萬設備(bei)接(jie)入量(liang)(liang)的(de)(de)服務(wu)簡直(zhi)就是杯水車薪,需要多少壓(ya)力(li)機難以估量(liang)(liang)。
再次能想到(dao)的(de)是(shi)(shi)Select方法批量(liang)管理(li)設(she)備的(de)Socket連接。問題又出現了(le),Select管理(li)的(de)異(yi)步IO也是(shi)(shi)有極限(xian)的(de),此(ci)方法最終還是(shi)(shi)放棄。
經(jing)過前面的分析(xi)、實(shi)(shi)踐最終方(fang)法確定(ding),采(cai)用異步IO的方(fang)式批量模擬設備連接(jie)服(fu)務(wu)器(qi),按(an)照一(yi)定(ding)的頻率上報(bao)注冊(ce)報(bao)文,不斷(duan)遍歷設備Socket接(jie)收的緩存數據,解析(xi)服(fu)務(wu)消息來判(pan)斷(duan)設備是否連接(jie)成功(gong),并通(tong)過周期性上報(bao)心跳來保持(chi)(chi)設備持(chi)(chi)續在線。實(shi)(shi)現細節如下:
(1)實(shi)現基礎設(she)備類:封裝部分MQTT協(xie)議報文方法,其中(zhong)包(bao)括設(she)備注冊(ce)、訂閱、發布、心跳等。

MQTT注冊報文封裝示(shi)例(Java)
(2)實現設(she)(she)備類:主要記錄設(she)(she)備注冊狀態、訂(ding)閱狀態、保活間隔(ge),最重要的服(fu)務消息的解析(xi)和響應方(fang)法,以(yi)及設(she)(she)備連(lian)接(jie)服(fu)務器的非阻(zu)塞Socket(Java中(zhong)的SocketChanel)

服務消息解析代碼示例(li)(Java)
(3)實(shi)現(xian)(xian)程序主體類:管理批量設備(bei),控制(zhi)設備(bei)注(zhu)冊頻率(lv),設備(bei)何時上報數據、監聽(ting)服務下發(fa)數據,統計設備(bei)連接(jie)數,持續上報心(xin)跳,保持設備(bei)在線(xian)等。具體實(shi)現(xian)(xian)邏輯如下:
批(pi)量初始化設(she)備列表;
同(tong)時啟動一(yi)下三(san)個線程;
啟動(dong)設(she)(she)備(bei)注(zhu)冊(ce)(ce)線程(cheng),初始化設(she)(she)備(bei)與服務連接并(bing)上行注(zhu)冊(ce)(ce)報(bao)文,可根(gen)據設(she)(she)置,指(zhi)定當前可同時注(zhu)冊(ce)(ce)的(de)設(she)(she)備(bei)數,所有設(she)(she)備(bei)注(zhu)冊(ce)(ce)完成后自(zi)動(dong)退出;
啟動連接統(tong)計線(xian)程,周(zhou)期(qi)性統(tong)計設(she)備連接成功個數(shu)、訂閱成功個數(shu)、連接失敗(bai)設(she)備等數(shu)據(ju);
啟(qi)動設備Socket遍(bian)歷線程(cheng),持(chi)續輪(lun)詢每(mei)個(ge)Socket的(de)接收數(shu)據(ju),對(dui)接收到的(de)數(shu)據(ju)處理和(he)響應(ying),每(mei)輪(lun)遍(bian)歷完畢對(dui)需要對(dui)未(wei)長(chang)時(shi)間未(wei)上報心(xin)跳的(de)設備上行(xing)心(xin)跳報文,以(yi)達到設備保活的(de)目的(de)。

程序主(zhu)題類接(jie)收(shou)線程邏輯代(dai)碼片段(duan)(Java)
完成程序代碼后,測試工(gong)具制作完成。
此工具已實際(ji)用于(yu)項目性能測試(shi)中(zhong),可將(jiang)壓(ya)力機全部可用端口用于(yu)最(zui)大設(she)備在(zai)線量的測試(shi)中(zhong),實際(ji)在(zai)Linux虛擬機中(zhong)幾(ji)分鐘內完(wan)成50000+設(she)備注冊(ce),并保持設(she)備長(chang)時(shi)間持續在(zai)線。
此工具(ju)能(neng)最大限度(du)利(li)用壓力機端口資源,提升測試執行效率,對于在線(xian)量較大的(de)服務,只需要在更多的(de)壓力機上運行此工具(ju)即可。