MQTT(訊息佇列遙測傳輸)是 ISO 標準(ISO/IEC PRF 20922)下基于發布/訂閱范式的訊息協議 ;本文主要介紹 MQTT 協議 3.1.1 的內容,
1、概述
1.1、背景
隨著 5G 時代的來臨,萬物互聯的偉大構想正在成為現實,聯網的 物聯網設備 在 2018 年已經達到了 70 億,在未來兩年,僅智能水電氣表就將超過 10 億,

海量的設備接入和設備管理對網路帶寬、通信協議以及平臺服務架構都帶來了很大挑戰,對于 物聯網協議 來說,必須針對性地解決物聯網設備通信的幾個關鍵問題:其網路環境復雜而不可靠、其記憶體和閃存容量小、其處理器能力有限,
MQTT 協議 是基于發布/訂閱模式的物聯網通信協議,憑借簡單易實作、支持 QoS、報文小等特點,占據了物聯網協議的半壁江山,
1.2、MQTT 協議的誕生
MQTT was created by Andy Stanford-Clark of IBM, and Arlen Nipper (then of Arcom Systems, later CTO of Eurotech).
據 Arlen Nipper 在一 IBM Podcast 上的自述,MQTT 原名是 MQ TT, 注意 MQ 與 TT之間的空格,其全稱為: MQ Telemetry Transport,是九十年代早期,他在參與 Conoco Phillips 公司的一個原油管道資料采集監控系統(pipeline SCADA system)時,開發的一個實時資料傳輸協議,它的目的在于讓傳感器通過帶寬有限的 VSAT ,與 IBM 的 MQ Integrator 通信,由于 Nipper 是遙感和資料采集監控專業出身,所以按業內慣例給了個 MQ TT 的名字,
2、MQTT 協議核心特點
按照 Nipper 的介紹,MQTT 必須簡單容易實作,必須支持 QoS(設備網路環境復雜),必須輕量且省帶寬(因為那時候帶寬很貴),必須資料無關(不關心 Payload 資料格式),必須有持續地會話感知能力(時刻知道設備是否在線),
2.1、發布訂閱模式
發布訂閱模式是傳統 Client/Server 模式的一種解耦方案,發布者通過 Broker 與消費者之間通信,Broker 的作用是將收到的訊息通過某種過濾規則,正確地發送給消費者,發布/訂閱模式 相對于 客戶端/服務器模式 的好處在于:
- 發布者和消費者之間不必預先知道對方的存在,比如不需要預先溝通對方的 IP Address 和 Port
- 發布者和消費者之間不必同時運行,因為 Broker 是一直運行的,
在 MQTT 協議里,上面提到的 過濾規則 是 Topic,比如:所有發布到 news 這個 Topic 的訊息,都會被 Broker 轉發給已經訂閱了 news 的訂閱者:

上圖中訂閱者預先訂閱了 news,然后發布者向 Broker 發布了一條訊息 "some msg" 并指定發布到 news 主題,Broker 通過 Topic 匹配,決定將這條訊息轉發給訂閱者,
MQTT 的 Topic 有層級結構,并且支持通配符 + 和 #:
+是匹配單層的通配符,比如news/+可以匹配news/sports,news/+/basketball可匹配到news/sports/basketball,#是一到多層的通配符,比如news/#可以匹配news、news/sports、news/sports/basketball以及news/sports/basketball/x等等,
MQTT 的主題是不要預先創建的,發布者發送訊息到某個主題、或者訂閱者訂閱某個主題的時候,Broker 就會自動創建這個主題,
2.2、帶寬消耗最小原則
MQTT 協議將協議本身占用的額外消耗最小化,訊息頭部最小只需要占用 2 個位元組,MQTT 的訊息格式分三部分:
| 固定長度頭部,2 個位元組,所有訊息型別里都有 |
|---|
| 可變長度頭部,只有某些訊息型別里有 |
| Payload,只有某些訊息型別里有 |
MQTT 的主要訊息型別有:
- CONNECT / CONNACK
- PUBLISH / PUBACK
- SUBSCRIBE / SUBACK
- UNSUBSCRIBE / UNSUBACK
- PINGREQ / PINGRESP
- DISCONNECT
其中 PINGREQ / PINGRESP 和 DISCONNECT 報文是不需要可變頭部的,也沒有 Payload,也就是說它們的報文大小僅僅消耗 2 個位元組,
在 CONNECT 報文的可變長度頭部里,有個 Protocol Version 的欄位,為了節省空間,只有一個位元組,所以版本號不是按照字串 "3.1.1" 存放的,而是使用數字 4 來表示 3.1.1 版本,
2.3、可選的 QoS 等級
為適應設備不同的網路環境,MQTT 設計了 3 個 QoS 等級,0, 1, 2:
- At most once (0)
- At least once (1)
- Exactly once (2)
QoS 0 是一種 "fire and forget" 的訊息發送模式:Sender (可能是 Publisher 或者 Broker) 發送一條訊息之后,就不再關心它有沒有發送到對方,也不設定任何重發機制,
QoS 1 包含了簡單的重發機制,Sender 發送訊息之后等待接收者的 ACK,如果沒收到 ACK 則重新發送訊息,這種模式能保證訊息至少能到達一次,但無法保證訊息重復,
QoS 2 設計了略微復雜的重發和重復訊息發現機制,保證訊息到達對方并且嚴格只到達一次,
2.4、會話保持
MQTT 沒有假設設備或 Broker 使用了 TCP 的保活機制,而是設計了協議層的保活機制:在 CONNECT 報文里可設定 Keepalive 欄位,來設定保活心跳包 PINGREQ/PINGRESP 的發送時間間隔,當長時間無法收到設備的 PINGREQ 的時候,Broker 就會認為設備已經下線,
總的來說,Keepalive 有兩個作用:
- 發現對端死亡或者網路中斷
- 在長時間無訊息互動的情況下,保持連接不被網路設備斷開
對于那些想要在重新上線后,重新收到離線期間錯過的訊息的設備,MQTT 設計了持久化連接:在 CONNECT 報文里可設定 CleanSession 欄位為 False,則 Broker 會為終端存盤:
- 設備所有的訂閱
- 還未被設備確認的 QoS1 和 QoS 訊息
- 設備離線時錯過的訊息
2.5、在線狀態感知
MQTT 設計了遺愿(Last Will) 訊息,讓 Broker 在發現設備例外下線的情況下,幫助設備發布一條遺愿訊息到指定的主題,
3、MQTT 5.0
MQTT 5.0 增加了許多新特性,詳細資訊可參考:https://www.emqx.com/zh/mqtt/mqtt5
參考:https://www.emqx.com/zh/blog/what-is-the-mqtt-protocol
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/482141.html
標籤:Java
下一篇:執行緒池的簡介說明
