1. 程式人生 > 其它 >MQTT 入門(1)--簡介

MQTT 入門(1)--簡介

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/sportsnews/+/basketball 可匹配到 news/sports/basketball
  • # 是一到多層的萬用字元。比如 news/# 可以匹配 news、 news/sportsnews/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