MQTT,弱網之友
背景
最近搭建私有云環境中使用了 MQTT,MQTT 作爲客戶端和服務端之之間的長連接中間件,主要用作客戶端和服務端之間的信息交換。順手寫個文章分享一下。
介紹
什麼是 MQTT
首先 MQTT 不是 MQ(消息隊列),只是名字帶有 MQ。
MQTT(Message Queuing Telemetry Transport),一種基於發佈 / 訂閱模式的消息傳輸協議,它設計輕巧、易於實現,非常適合需要低帶寬、高延遲或不可靠網絡的應用場景,基於 TCP/IP 協議建立。
架構
從架構圖可以看出,基於 發佈 / 訂閱 模式的的 MQTT 架構是比較簡單的。
設備(客戶端,比如溫度傳感器)發佈消息(比如 溫度)到特定的主題,而其他感興趣的設備(訂閱者,比如警報系統)可以訂閱這些主題以接收消息。這種模式解耦了消息的發佈者和訂閱者,使得系統更加靈活和可擴展。
一些術語
Broker
MQTT Broker 是 MQTT 系統中的中間件,負責接收來自發布者的報文,處理這些報文,並將其分發給訂閱相應主題的訂閱者。
Broker 是消息路由和分發的核心。
MQTT Broker 一般只負責消息轉發,不存儲信息。可以將 MQTT Broker 理解爲郵局,將收到的信件(消息)進行分類(主題)並轉發給對應的人(訂閱者)。
主題(Topic)
MQTT 使用主題來區分消息的類型。主題是一個字符串,用於匹配發布者和訂閱者之間的消息。
主題可以包含層次結構,類似於文件系統的路徑,例如 “wushihong/topic/1”。
發佈者(Publisher)
發佈者是發送消息到 MQTT 主題的客戶端。它可以發送不同服務質量(QoS)等級的消息。
訂閱者(Subscriber)
訂閱者是接收特定主題消息的客戶端。訂閱者指定它感興趣的主題,並接收來自這些主題的消息。
關鍵內容
服務質量
MQTT 提供了三個級別的服務質量(QoS):
-
QoS 0:最多一次(At most once),消息可能丟失,但傳輸效率最高,不保證消息的到達。
-
QoS 1:至少一次(At least once),確保消息至少被傳輸一次,但可能會有重複。
-
QoS 2:只有一次(Exactly once),確保消息只傳輸一次,提供最高的可靠性保證。
消息類型
MQTT 定義了幾種不同類型的控制報文,包括:
-
CONNECT:客戶端連接到服務器。
-
CONNACK:連接響應。
-
PUBLISH:發佈消息。
-
PUBACK:發佈消息確認(QoS 1)。
-
PUBREC:發佈消息接收(QoS 2)。
-
PUBREL:發佈消息釋放(QoS 2)。
-
PUBCOMP:發佈消息完成(QoS 2)。
-
SUBSCRIBE:訂閱主題。
-
SUBACK:訂閱響應。
-
UNSUBSCRIBE:取消訂閱主題。
-
UNSUBACK:取消訂閱響應。
-
PINGREQ:心跳請求。
-
PINGRESP:心跳響應。
-
DISCONNECT:斷開連接。
下面通過使用演示
保留標誌
MQTT 的 PUBLISH 報文中的保留標誌(Retain Flag)用於指示服務器在消息被髮送後,是否應該保留這條消息,並將其轉發給後續的訂閱者。
如果保留標誌被設置,服務器會存儲這條消息,並將其發送給所有新訂閱該主題的客戶端,直到一條新的帶有保留標誌的消息被髮布,或者服務器端的保留消息被顯式刪除。
保留消息通常用於發送者向所有當前和未來的訂閱者廣播消息,例如,設備的當前狀態或告警信息。
爲什麼要用 MQTT
-
輕量和簡單:MQTT 協議頭最小隻有 2 字節,相比 HTTP 小的多,更適合帶寬有限的環境
-
低功耗:適合電池供電的設備,有助於延長設備的使用壽命
-
高可靠性:提供了三種不同的服務質量(QoS)等級,確保消息在不同網絡條件下的可靠傳輸
-
易於擴展:支持大量併發連接,適合物聯網(IoT)場景,其中可能涉及數以百萬計的設備
-
雙向通信:支持設備到雲端(Device-to-Cloud)和雲端到設備(Cloud-to-Device)的雙向通信
區別於 MQ
-
MQ 指的是消息隊列系統,是一種軟件服務,用於在分佈式系統中存儲、傳遞和接收消息
-
MQTT 可以被視爲一種應用層協議
-
MQTT Broker 是一種實現 MQTT 協議的服務器,負責接收、過濾和分發來自客戶端的所有消息,並根據訂閱關係將消息發送給相應的客戶端
整合於 MQ
一般情況下,MQTT 可以 和 MQ 結合使用,MQTT 可以作爲消息的接入協議,而 MQ 系統可以作爲後端處理消息的隊列系統。
-
輕量級和高效:MQTT 協議設計輕量,適合帶寬有限和網絡不穩定的環境,而 MQ 系統通常用於處理更復雜的數據處理和路由功能。
-
可靠性:MQTT 提供了三種不同的消息服務質量(QoS)級別確保消息的可靠傳遞;MQ 系統則提供了持久化存儲消息的能力,確保即使在系統故障的情況下也不會丟失消息。
-
靈活性和擴展性:MQTT 的發佈 / 訂閱模型非常靈活,允許客戶端動態地訂閱和取消訂閱主題。MQ 系統則可以處理大量的消息傳遞和隊列管理.
遇到過的問題
- 單位時間內客戶端單個主題發送消息的數量
本次我使用的 MQTT Broker 是經過二次開發的,支持配置單個客戶端單個主題的單位時間內發送消息條數,開發過程有同事修改了配置導致訂閱者收不到消息。
發行版的 EMQX 也有相關配置,可以限制單個客戶端的發佈速率。
而 MQTT 5.0 有類似配置 Receive Maximum,用於告知 Broker 客戶端願意接收的最大消息數。雖然這不是直接限制發送速率,但它可以幫助調整客戶端和 Broker 之間的消息流量。
- 客戶端的自動重連機制
由於我們的客戶端需要在斷連後加入業務,因此沒有直接使用 SDK 的自動重連。但是也帶來了一些問題,比如重連的觸發時間、重試間隔、連接狀態記錄等都需要注意。
所以如果沒有特殊的業務要求可以直接使用 SDK 的自動重連,只需要實現 SDK 中斷連的回調函數即可簡單處理斷連後觸發的業務。
- 斷聯過程中的消息丟失問題
考慮到客戶端斷網狀態下的消息丟失,客戶端在連接時必須設置cleanSession false
(不清理 session),並且 Broker 需要支持消息持久化功能。
設置cleanSession
爲 false
,Broker 就會保留客戶端的訂閱信息和未發送的消息,客戶端在重新連接後可以繼續接收之前訂閱的主題的消息。
而 Broker 消息持久化,可以通過設置persistence true
來啓用。
部署演示
win 環境,本地部署
1、下載 mosquitto 並安裝
2、修改 mosquitto.conf
# 1、端口
#listener
listener 1883
# 2、方便演示 允許匿名登錄
allow_anonymous = true
3、啓動
.\mosquitto -c mosquitto.conf
4、爲了直觀演示主題訂閱、消息發送、和消息接收,這裏使用 MQTTX 可是化客戶端演示
可視化客戶端演示
5、爲了觀察過程,這裏用命令行再演示一次 主題訂閱、消息發送、消息接收
5.1、 QoS 0
訂閱和發佈
# -d 開啓debug消息
# -v 打印更多的調試信息
# -t 指定主題,此處爲 wushihong/topic/1
# --QoS 設置QoS,默認0
.\mosquitto_sub -v -t wushihong/topic/1
# -d 開啓debug消息
# -t 指定主題,此處爲 wushihong/topic/1
# -m 發佈的消息內容,此處爲 helloworld
# --QoS 設置QoS,默認0
.\mosquitto_pub -d -t wushihong/topic/1 -m 'helloworld'
可以看到客戶端和服務端一些報文,有 CONNECT、CONNACK、SUBSCRIBE、PUBLISH 等不一一列舉,可以參考上面的報文類型解釋。
5.3、使用 QoS 1 發佈消息
QoS 2 的發佈者和訂閱者都多了比上面 QoS 1 的多了 PUBACK 報文。
5.4、使用 QoS 2 發佈消息
QoS 2 比 QoS 1 多了 3 個報文,分別是 PUBREC(發佈消息接收)、PUBREL(發佈消息釋放) 和 PUBCOMP(發佈消息完成)。其中 m1 指的是消息 ID,rc0 表示沒有錯誤(return code 0)。
其實就是一個握手的過程,篇幅有限不一一解釋。
需要注意的是,訂閱者和發佈者的 QoS 不一致時,訂閱者接收消息會以兩者中取最小值 QoS
集羣
生產環境一般都需要集羣部署,不會採用上面演示的單節點的方式。
使用 MQTT Broker 集羣的主要優勢在於它能夠提供高可擴展性、高可用性、負載均衡、集中管理和靈活的維護能力。
MQTT Broker 集羣有多種實現方式,比如 分佈式集羣架構、主從集羣架構、橋接集羣架構等,每種架構都有其特定的優勢和適用場景,選擇合適的集羣架構取決於具體的業務需求和預期的負載。
例如,對於需要高併發連接和高吞吐量的場景,分佈式集羣架構可能是最合適的選擇。而對於需要高可用性和故障轉移能力的場景,主從集羣架構可能更合適。
最後
總的來說,MQTT 很適合低帶寬、高延遲或不可靠網絡的應用場景。
我們本次部署針對局域網內的,不過現在物聯網越來越普遍,部署在公網的 MQTT broker 非常常見,現在各大雲廠商也都有 MQTT 的雲服務,安全性也來越好。所以後續應該也會考慮上雲。
參考:
MQTT: https://MQTT.org/
mosquitto: https://mosquitto.org/
emqx: https://www.emqx.com/
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/3swGV9waey6LJoIgRh1EQQ