為什么 MQTT 是適合物聯(lián)網(wǎng)的網(wǎng)絡(luò)協(xié)議
物聯(lián)網(wǎng) (IoT) 設(shè)備必須連接互聯(lián)網(wǎng)。通過連接到互聯(lián)網(wǎng),設(shè)備就能相互協(xié)作,以及與后端服務(wù)協(xié)同工作?;ヂ?lián)網(wǎng)的基礎(chǔ)網(wǎng)絡(luò)協(xié)議是 TCP/IP。MQTT(消息隊(duì)列遙測(cè)傳輸) 是基于 TCP/IP 協(xié)議棧而構(gòu)建的,已成為 IoT 通信的標(biāo)準(zhǔn)。
MQTT 初由 IBM 于上世紀(jì) 90 年代晚期發(fā)明和開發(fā)。它初的用途是將石油管道上的傳感器與衛(wèi)星的相鏈接。顧名思義,它是一種支持在各方之間異步通信的消息協(xié)議。異步消息協(xié)議在空間和時(shí)間上將消息發(fā)送者與接收者分離,因此可以在不可靠的網(wǎng)絡(luò)環(huán)境中進(jìn)行擴(kuò)展。雖然叫做消息隊(duì)列遙測(cè)傳輸,但它與消息隊(duì)列毫無關(guān)系,而是使用了一個(gè)發(fā)布和訂閱的模型。在 2014 年末,它正式成為了一種 OASIS 開放標(biāo)準(zhǔn),而且在一些流行的編程語言中受到支持(通過使用多種開源實(shí)現(xiàn))。
為何選擇 MQTT
MQTT 是一種輕量級(jí)的、靈活的網(wǎng)絡(luò)協(xié)議,致力于為 IoT 開發(fā)人員實(shí)現(xiàn)適當(dāng)?shù)钠胶猓?/span>
這個(gè)輕量級(jí)協(xié)議可在嚴(yán)重受限的設(shè)備硬件和高延遲/帶寬有限的網(wǎng)絡(luò)上實(shí)現(xiàn)。
它的靈活性使得為 IoT 設(shè)備和服務(wù)的多樣化應(yīng)用場(chǎng)景提供支持成為可能。
為了了解為什么 MQTT 如此適合 IoT 開發(fā)人員,我們首先來分析一下為什么其他流行網(wǎng)絡(luò)協(xié)議未在 IoT 中得到成功應(yīng)用。
為什么不選擇HTTP
大多數(shù)開發(fā)人員已經(jīng)熟悉 HTTP Web 服務(wù)。那么為什么不讓 IoT 設(shè)備連接到 Web 服務(wù)?設(shè)備可采用 HTTP 請(qǐng)求的形式發(fā)送其數(shù)據(jù),并采用 HTTP 響應(yīng)的形式從系統(tǒng)接收更新。這種請(qǐng)求和響應(yīng)模式存在一些嚴(yán)重的局限性:
1.HTTP 是一種同步協(xié)議??蛻舳诵枰却?wù)器響應(yīng)。Web 瀏覽器具有這樣的要求,但它的代價(jià)是沒了可伸縮性。在 IoT 領(lǐng)域,大量設(shè)備以及很可能不可靠或高延遲的網(wǎng)絡(luò)使得同步通信成為問題。異步消息協(xié)議更適合 IoT 應(yīng)用程序。傳感器發(fā)送讀數(shù),讓網(wǎng)絡(luò)確定將其傳送到目標(biāo)設(shè)備和服務(wù)的佳路線和時(shí)間。
2.HTTP 是單向的??蛻舳吮仨毎l(fā)起連接。在 IoT 應(yīng)用程序中,設(shè)備或傳感器通常是客戶端,這意味著它們無法被動(dòng)地接收來自網(wǎng)絡(luò)的命令。
3.HTTP 是一種 1-1 協(xié)議??蛻舳税l(fā)出請(qǐng)求,服務(wù)器進(jìn)行響應(yīng)。將消息傳送到網(wǎng)絡(luò)上的所有設(shè)備上,不但很困難,而且成本很高,而這是 IoT 應(yīng)用程序中的一種常見使用情況。
4.HTTP 是一種有許多標(biāo)頭和規(guī)則的重量級(jí)協(xié)議。它不適合受限的網(wǎng)絡(luò)。

方法method:
這個(gè)很重要,比如說GET和POST方法,這兩個(gè)是很常用的,GET就是獲取什么內(nèi)容,而POST就是向服務(wù)器發(fā)送什么數(shù)據(jù)。當(dāng)然還有其他的,比如HTTP 1.1中還有:DELETE、PUT、CONNECT、HEAD、OPTIONS、TRACE等一共8個(gè)方法(HTTP Method歷史:HTTP 0.9 只有GET方法;HTTP 1.0 有GET、POST、HEAD三個(gè)方法)。
請(qǐng)求URL:
這里填寫的URL是不包含IP地址或者域名的,是主機(jī)本地文件對(duì)應(yīng)的目錄地址,所以我們一般看到的就是“/”。
版本version:
格式是HTTP/<major>.<minor>這樣的格式,比如說HTTP/1.1.這個(gè)版本就是我們使用的HTTP協(xié)議的版本,現(xiàn)在使用的一般是HTTP/1.1
狀態(tài)碼status:
狀態(tài)碼是三個(gè)數(shù)字,是請(qǐng)求過程中所發(fā)生的情況,比如說200是成功,404是找不到文件。
原因短語reason-phrase:
是狀態(tài)碼的可讀版本,狀態(tài)碼就是一個(gè)數(shù)字,如果你事先不知道這個(gè)數(shù)字什么意思,可以先查看一下原因短語。
首部header:
注意這里的header我們不是叫做頭,而是叫做首部??赡苡辛銈€(gè)首部也可能有多個(gè)首部,每個(gè)首部包含一個(gè)名字后面跟著一個(gè)冒號(hào),然后是一個(gè)可選的空格,接著是一個(gè)值,然后換行。
實(shí)體的主體部分entity-body:
實(shí)體的主體部分包含一個(gè)任意數(shù)據(jù)組成的數(shù)據(jù)塊,并不是所有的報(bào)文都包含實(shí)體的主體部分,有時(shí)候只是一個(gè)空行加換行就結(jié)束了。
那么,MQTT 為什么如此輕量且靈活?MQTT 協(xié)議的一個(gè)關(guān)鍵特性是發(fā)布和訂閱模型。與所有消息協(xié)議一樣,它將數(shù)據(jù)的發(fā)布者與使用者分離。
它具有以下主要的幾項(xiàng)特性:
1、使用發(fā)布/訂閱消息模式,提供一對(duì)多的消息發(fā)布和應(yīng)用程序之間的解耦;
2、消息傳輸不需要知道負(fù)載內(nèi)容;
3、使用 TCP/IP 提供網(wǎng)絡(luò)連接;
4、有三種消息發(fā)布的服務(wù)質(zhì)量:
QoS 0:“多一次”,消息發(fā)布完全依賴底層 TCP/IP 網(wǎng)絡(luò)。分發(fā)的消息可能丟失或重復(fù)。例如,這個(gè)等級(jí)可用于環(huán)境傳感器數(shù)據(jù),單次的數(shù)據(jù)丟失沒關(guān)系,因?yàn)椴痪煤筮€會(huì)有第二次發(fā)送。
QoS 1:“至少一次”,確保消息可以到達(dá),但消息可能會(huì)重復(fù)。
QoS 2:“只有一次”,確保消息只到達(dá)一次。例如,這個(gè)等級(jí)可用在一個(gè)計(jì)費(fèi)系統(tǒng)中,這里如果消息重復(fù)或丟失會(huì)導(dǎo)致不正確的收費(fèi)。
5、小型傳輸,開銷很?。ü潭ㄩL度的頭部是 2 字節(jié)),協(xié)議交換小化,以降低網(wǎng)絡(luò)流量;
6、使用 Last Will 和 Testament 特性通知有關(guān)各方客戶端異常中斷的機(jī)制;
在MQTT協(xié)議中,一個(gè)MQTT數(shù)據(jù)包由:固定頭(Fixed header)、 可變頭(Variable header)、 消息體(payload)三部分構(gòu)成。MQTT的傳輸格式非常精小,小的數(shù)據(jù)包只有2個(gè)bit,且無應(yīng)用消息頭。
發(fā)布和訂閱模型
MQTT 協(xié)議在網(wǎng)絡(luò)中定義了兩種實(shí)體類型:一個(gè)消息代理和一些客戶端。代理是一個(gè)服務(wù)器,它從客戶端接收所有消息,然后將這些消息路由到相關(guān)的目標(biāo)客戶端。客戶端是能夠與代理交互來發(fā)送和接收消息的任何事物??蛻舳丝梢允乾F(xiàn)場(chǎng)的 IoT 傳感器,或者是數(shù)據(jù)中心內(nèi)處理 IoT 數(shù)據(jù)的應(yīng)用程序。
客戶端連接到代理。它可以訂閱代理中的任何消息 “主題”。此連接可以是簡單的 TCP/IP 連接,也可以是用于發(fā)送敏感消息的加密 TLS 連接。
客戶端通過將消息和主題發(fā)送給代理,發(fā)布某個(gè)主題范圍內(nèi)的消息。
代理然后將消息轉(zhuǎn)發(fā)給所有訂閱該主題的客戶端。
因?yàn)?MQTT 消息是按主題進(jìn)行組織的,所以應(yīng)用程序開發(fā)人員能靈活地指定某些客戶端只能與某些消息交互。例如,傳感器將在 “sensor_data” 主題范圍內(nèi)發(fā)布讀數(shù),并訂閱 “config_change” 主題。將傳感器數(shù)據(jù)保存到后端數(shù)據(jù)庫中的數(shù)據(jù)處理應(yīng)用程序會(huì)訂閱 “sensor_data” 主題。管理控制臺(tái)應(yīng)用程序能接收系統(tǒng)管理員的命令來調(diào)整傳感器的配置,比如靈敏度和采樣頻率,并將這些更改發(fā)布到 “config_change” 主題。
同時(shí),MQTT 是輕量級(jí)的。它有一個(gè)用來指定消息類型的簡單標(biāo)頭,有一個(gè)基于文本的主題,還有一個(gè)任意的二進(jìn)制有效負(fù)載。應(yīng)用程序可對(duì)有效負(fù)載采用任何數(shù)據(jù)格式,比如 JSON、XML、加密二進(jìn)制或 Base64,只要目標(biāo)客戶端能夠解析該有效負(fù)載。