MQTT全名為Message Queuing Telemetry Transport,是一種基于TCP/IP協議上傳輸的輕量級通信協議。MQTT協議是一種消息隊列傳輸協議,采用訂閱、發布機制,訂閱者只接受自己已經訂閱的數據,非訂閱數據則不接受,既保證了必要的數據交換,又避免了無效數據造成的存儲與處理。因此在工業物聯網中得到廣泛的應用。
MQTT協(xie)議(yi)是物聯網平臺的(de)(de)最通用協(xie)議(yi)之一,也是OneNET平臺的(de)(de)首要設備接入協(xie)議(yi)。物聯網平臺必須海(hai)量設備接入,但MQTT接入服務究(jiu)竟(jing)能同時支持多少(shao)設備同時在(zai)線呢(ni)?了解這個指(zhi)標(biao)能更(geng)好地為平臺的(de)(de)運(yun)(yun)維和運(yun)(yun)營提供科學的(de)(de)依(yi)據。
可(ke)是,如何快速簡(jian)便地測試最大在(zai)線量指標呢(ni)?如何選取(qu)工具(ju)和制作(zuo)腳本呢(ni)?
測(ce)試性能我們首先想到的(de)(de)是(shi)常(chang)用的(de)(de)Jmeter和Locust等性能測(ce)試工具。但是(shi)這些(xie)工具的(de)(de)優勢在測(ce)試服務(wu)的(de)(de)并(bing)發和吞(tun)吐量,并(bing)不適合當(dang)前的(de)(de)測(ce)試場景。
然后能想(xiang)到的(de)(de)是利用第(di)三方(fang)(fang)Jar包(bao)或者三方(fang)(fang)庫實現的(de)(de)協議庫,采用多(duo)線程啟動設(she)備(bei)。但是壓力機線程啟動有(you)限(xian),對動則支持幾(ji)十(shi)萬上百萬設(she)備(bei)接入(ru)量的(de)(de)服務簡直就是杯水(shui)車薪,需要多(duo)少壓力機難以估量。
再(zai)次能想到(dao)的(de)(de)是(shi)Select方法批量(liang)管(guan)(guan)理設(she)備(bei)的(de)(de)Socket連接(jie)。問題又出(chu)現了,Select管(guan)(guan)理的(de)(de)異步IO也是(shi)有極(ji)限(xian)的(de)(de),此方法最終(zhong)還是(shi)放棄。
經(jing)過(guo)前(qian)面(mian)的分析(xi)、實踐(jian)最終方法確定,采用異步IO的方式批(pi)量(liang)模擬(ni)設(she)備連(lian)接服務器(qi),按(an)照一定的頻率上報注冊報文(wen),不(bu)斷遍(bian)歷設(she)備Socket接收的緩存(cun)數據,解析(xi)服務消(xiao)息來判斷設(she)備是否(fou)連(lian)接成功,并通(tong)過(guo)周期(qi)性上報心(xin)跳來保持設(she)備持續(xu)在(zai)線。實現(xian)細(xi)節如下:
(1)實現基礎設(she)備類:封裝部分MQTT協議報文方法,其中(zhong)包(bao)括設(she)備注冊、訂閱、發布、心跳等。
MQTT注冊(ce)報(bao)文封裝示例(li)(Java)
(2)實(shi)現設備(bei)(bei)類:主(zhu)要記錄設備(bei)(bei)注冊狀(zhuang)態、訂閱狀(zhuang)態、保活間隔,最重(zhong)要的服務(wu)消息(xi)的解(jie)析和(he)響應(ying)方法,以及設備(bei)(bei)連接服務(wu)器的非(fei)阻(zu)塞Socket(Java中的SocketChanel)
服(fu)務消息解(jie)析代碼示例(Java)
(3)實(shi)現(xian)程序主體類:管理(li)批量設(she)(she)備(bei),控制設(she)(she)備(bei)注冊頻率(lv),設(she)(she)備(bei)何時上(shang)報數據(ju)、監(jian)聽服務下(xia)發數據(ju),統計設(she)(she)備(bei)連(lian)接數,持續上(shang)報心跳,保持設(she)(she)備(bei)在(zai)線等。具(ju)體實(shi)現(xian)邏(luo)輯如下(xia):
批量(liang)初始(shi)化設備列(lie)表;
同時啟動(dong)一下(xia)三個線程;
啟動(dong)設備(bei)(bei)(bei)注(zhu)冊線程,初(chu)始(shi)化設備(bei)(bei)(bei)與服(fu)務連接(jie)并上行注(zhu)冊報文,可根(gen)據設置,指定當(dang)前可同(tong)時(shi)注(zhu)冊的設備(bei)(bei)(bei)數,所有設備(bei)(bei)(bei)注(zhu)冊完成后自(zi)動(dong)退(tui)出(chu);
啟動(dong)連(lian)接(jie)統(tong)計(ji)線程,周期(qi)性(xing)統(tong)計(ji)設(she)備(bei)連(lian)接(jie)成功個數(shu)、訂(ding)閱成功個數(shu)、連(lian)接(jie)失敗設(she)備(bei)等數(shu)據;
啟(qi)動設(she)備(bei)Socket遍歷線程,持續輪詢(xun)每個Socket的接(jie)收數(shu)據,對(dui)接(jie)收到(dao)的數(shu)據處(chu)理和響應,每輪遍歷完(wan)畢對(dui)需要(yao)對(dui)未長時間未上(shang)報心跳的設(she)備(bei)上(shang)行心跳報文,以達到(dao)設(she)備(bei)保(bao)活的目的。
程(cheng)序(xu)主題類(lei)接收線程(cheng)邏輯代碼片(pian)段(Java)
完(wan)成程序(xu)代碼后(hou),測試工(gong)具(ju)制作完(wan)成。
此(ci)工具已(yi)實際(ji)用于項目性能測試中,可將壓(ya)力(li)機全部可用端口用于最大設備(bei)在線(xian)量的測試中,實際(ji)在Linux虛(xu)擬機中幾分(fen)鐘(zhong)內完(wan)成50000+設備(bei)注冊,并(bing)保(bao)持設備(bei)長時間持續在線(xian)。
此工(gong)具(ju)能最大限度利用壓力機(ji)端口資源,提升測試執行效率,對(dui)于在線量(liang)較(jiao)大的服務,只(zhi)需要在更(geng)多的壓力機(ji)上運行此工(gong)具(ju)即可。