原文鏈接:A Brief, but Practical Introduction to the MQTT Protocol and its Application to IoT
作者:Ben Howes
譯者:孫薇
責(zé)編:周建丁([email protected])
MQTT (Message Queuing Telemetry Transport,消息隊列遙測傳輸) 是一種標(biāo)準(zhǔn)化的發(fā)布/訂閱消息傳輸協(xié)議,設(shè)計于1999年,最初是為了在衛(wèi)星之類的物體上使用。它是一個非常輕量級的協(xié)議,由于對帶寬需求很低,從而成為了 M2M 通信或物聯(lián)網(wǎng)應(yīng)用的理想選擇,現(xiàn)在已經(jīng)成為這類場景最常見的協(xié)議之一。
本文會對該協(xié)議及一些使用范例做以簡介,雖然沒打算寫成 MQTT 的綜合性參考指南,但會提供足夠的信息,讓開發(fā)人員了解到如何安裝運行這一協(xié)議。如果想要更深入地了解,可以參考 HiveMQ 所發(fā)布的系列文章。
發(fā)布/訂閱
發(fā)布/訂閱,通常也被成為 pub-sub 模式是 MQTT 的核心,除了基于同一個消息代理的發(fā)布者和訂閱者之外,還有一些其它節(jié)點圍繞著該消息代理呈星型拓?fù)浞植?。這個模型與標(biāo)準(zhǔn)的客戶端/服務(wù)器迥然不同,一開始看似有些奇怪,但它提供的去耦能力在很多情況下都有巨大的優(yōu)勢。
客戶端可以發(fā)布或訂閱特定的主題(topic,有些類似信息主題),根據(jù)使用它們的消息代理來決定誰會收到信息。MQTT 的主題有特定的語法,使用斜杠(/)作為分隔符,整體呈層次結(jié)構(gòu),非常類似 URL 中的路徑格式,因此廚房中的溫度傳感器也許會發(fā)布到類似“sensors/temperature/home/kitchen” 這樣的主題。
我們看一個例子:想象一下有一個網(wǎng)絡(luò),將全世界的溫度傳感器連接起來,提供氣象服務(wù)。所有這些傳感器保持與某個消息代理中間件相連接,每隔10分鐘報告一次當(dāng)前的溫度。他們基于自身位置按照下面的格式向特定主題發(fā)布信息:
sensors/temperature/{country}/{city}/{street name}
那么在倫敦貝克街(Baker Street)的某個傳感器就會向“sensors/temperature/uk/london/baker_street”發(fā)布一條包含當(dāng)前溫度的信息。

MQTT 示例拓?fù)?/p>
氣象服務(wù)需要保證歷史溫度數(shù)據(jù)庫的數(shù)據(jù)最新,因此創(chuàng)建了訂閱到 MQTT主題的數(shù)據(jù)庫服務(wù),數(shù)據(jù)庫服務(wù)會在收到最新溫度信息時發(fā)出提示。不過這里存在一個問題:數(shù)據(jù)庫服務(wù)需要了解到全世界所有的溫度傳感器,而將每個傳感器訂閱到獨立的主題會非常復(fù)雜,幸好 MQTT 有相應(yīng)的解決方案:通配符(wildcards)。
通配符
在 MQTT 中有兩個可用的通配符,分別是+和#,+表示匹配單一層級中的任意主題,#表示匹配任意數(shù)量的層次。因此在全球溫度數(shù)據(jù)庫中可能會有訂閱到 sensors/temperature/# 的服務(wù),它能從全世界的任何一個傳感器接收溫度讀數(shù)。但如果英國政府想要在自己的溫度服務(wù)中利用這些數(shù)據(jù),只要訂閱到 sensors/temperature/uk/# ,就可以限制范圍,只接受英國的傳感器讀數(shù)。如果某個服務(wù)想要接收某個特定位置所有類型的傳感器數(shù)據(jù),可以使用類似這樣的格式:
sensors/+/uk/london/bakerstreet_
正如你所見,這是一個極優(yōu)秀的模塊化系統(tǒng),添加新的傳感器與數(shù)據(jù)庫只是小事一樁。而且該系統(tǒng)在性能方面也很優(yōu)秀,MQTT 消息代理可以高度并行化并采用事件驅(qū)動,從而使得單個消息代理可以輕易擴展到每秒處理數(shù)萬條信息的級別。
服務(wù)質(zhì)量(QoS)
MQTT 的設(shè)計初衷是為了在不可靠的網(wǎng)絡(luò)中運作良好,為不同的場景提供了三個級別的服務(wù)質(zhì)量,允許客戶端指定自己想要的可靠性級別。
QoS Level 0:至多一次
這是最簡單的級別,無需客戶端確認(rèn),其可靠性與基礎(chǔ)網(wǎng)絡(luò)層 TCP/IP 一致。
QoS Level 1:至少一次,有可能重復(fù)
確保至少向客戶端發(fā)送一次信息,不過也可發(fā)送多次;在接收數(shù)據(jù)包時,需要客戶端返回確認(rèn)消息(ACK 包)。這種方式常用于傳遞確保交付的信息,但開發(fā)人員必須確保其系統(tǒng)可以處理重復(fù)的數(shù)據(jù)包。
QoS Level 2:只有一次,確保消息只到達一次
這是最不常見的服務(wù)質(zhì)量級別,確保消息發(fā)送且僅發(fā)送一次。這種方法需要交換4個數(shù)據(jù)包,同時也會降低消息代理的性能。由于相對比較復(fù)雜,在 MQTT 實現(xiàn)中通常會忽略這個級別,請確保在選擇數(shù)據(jù)庫或消息代理前檢查這個問題。