MQTT協議詳解及v5.0實踐
MQTT是基於TCP/IP協議棧構建的非同步通訊訊息協議,是一種輕量級的釋出、訂閱資訊傳輸協議。可在不可靠的網路環境中進行擴充套件,適用於裝置硬體儲存空間或網路頻寬有限的場景。 MQTT已逐漸成為IoT領域最熱門的協議,也是國內外各大物聯網平臺最主流的傳輸協議,阿里雲IoT平臺很多裝置都是透過MQTT接入。 本文將詳細介紹MQTT協議的歷史演進,以及阿里雲IoT平臺在MQTT協議層實踐中的一些關鍵設計及思考。
本文主要包含了以下內容:
1)MQTT協議演進歷史及協議特點,總結和分析MQTT協議族的優缺點,分析和總結了為什麼相比於其他協議,MQTT適合IoT,業內支援現狀等。
2)阿里雲IoT MQTT3和5協議在實踐中的一些關鍵設計及思考。 包括連線複用、裝置狀態一致性、擴充套件增值能力設計等。
1. MQTT協議詳解
1.1 MQTT協議演進
MQTT最初由IBM於20世紀90年代發明,最初是用於石油管道的感測器與衛星之間資料傳輸。MQTT v3.1.1於2014.10月正式釋出,與此同時v3.1.1已成為OASIS協議標準(就是3.1.1已升級為國際物聯網標準)。正如HTTP為人們透過web分享資訊鋪平了道路一樣,MQTT標準化能將幾十億低成本、IoT裝置連線到網路。毫無疑問,MQTT是當前最主流、增長最迅速的IoT應用層傳輸協議,目前,阿里雲IoT平臺許多線上裝置都是透過MQTT接入的。
MQTT v5.0 於2018.5月正式釋出,2019年3月,v5.0 成為了新的 OASIS 標準。v5.0在 v3.1.1的基礎上做了較大的改變且不做向下相容,顯然是有太多的新東西要被引入,所有現有的實現要重新實現。 此次透過的 v5.0是自2014年的v3.1.1以來最重要的協議升級,新協議能適應近年來行業發展的新需求,同時也為未來物聯網行業發展的做了協議上的準備。 阿里雲IoT平臺從2020.1月開始支援 MQTT5.0。
1.2 MQTT協議族
每一種協議都是在特定上下文、約束下得出的折中設計,從來都沒有完美的協議。 MQTT經過幾十年的發展,針對不同場景已經演進出相對成熟的多版本協議。
1.2.1 MQTTv3
MQTTv3協議是為在低頻寬、不可靠的網路上工作的感測器而設計的基於TCP的應用層協議,適用於IoT場景。 MQTT報文設計緊湊,可在嚴重受限的硬體裝置和低頻寬/高延遲的網路上實現穩定傳輸。它具有以下幾項重要特性:使用釋出/訂閱訊息模式,支援一對多的訊息分發,解除裝置和業務之間的耦合; 報文格式設計精簡, 適用於小規模資料傳輸以及資源受限的IoT裝置。 固定頭部是2位元組,開銷很小,支援QoS0、QoS1、QoS2 三種訊息QoS。
MQTT3.1.1在MQTTv3基礎上引入了一些新特性, 主要包括:clientId最佳化,支援broker給裝置指定clientId,增大了clientId最大長度。ack響應最佳化,connect ack中引入session Present標識,告訴裝置當前broker有上次連線的會話資訊,裝置可以根據這個標記減少重複訂閱等步驟。裝置能夠在等broker返回connect ack之前釋出訊息,這個特性有點類似tls的false start, 適用於對於突發模式的裝置端。
MQTTv3/v3.1.1 在實際應用中存在以下不足:1)錯誤碼設計的不夠完整,裝置難以完整感知到broker的處理異常;2)不支援裝置跟broker之間的能力發現/協商,broker不能提供可選能力等。3)協議設計的過於精簡,沒有預留擴充套件空間,無法直接在協議層做擴充套件,協議能力相對簡陋。4)對於一些高階能力支援不夠,例如協議層缺乏流控、優先順序、報頭壓縮等功能。5)MQTT3是基於TCP的應用層協議,TCP固有的一些缺點也被MQTT繼承了。
1.2.2 MQTT-SN
MQTT-SN(Sensor Networks) 是MQTT協議的感測器網路版本,最早用在zigBee無線網路中,主要面對電池供電,有限的處理器能力和儲存能力的裝置。只有很小的記憶體和CPU,TCP 對於這些裝置來說非常奢侈,甚至無法允許TCP協議棧。 還有一些網路,比如 zigBee,報文的長度在幾百位元組以下,無法承載太大的資料包。MQTT-SN有主要特點:1) MQTT-SN支援執行在鏈路層、IP、UDP之上。2) QOS增加了-1級別,只用於傳輸,盡力而為,無保證。3)更豐富且開銷更低的Topic型別。4)網路架構增加了SN閘道器。
1.2.3 MQTTv5
MQTT 5.0在協議層提供了更大的自定義擴充套件空間,平臺基於擴充套件點可支援更豐富的協議能力。v3.1版本中,只能透過overlay方式,在業務層提供擴充套件能力。
MQTT5.0 主要特點如下:
設計目標 |
功能點 |
備註 |
提高錯誤反饋能力 |
Reason code& string on all ACKs |
ack有了錯誤碼,端上處理可以更靈活。例如qos1如果被限流,端上可以根據code主動減緩速率 |
Server disconnect |
端上根據斷開原因,能採用更合理的重連退避策略(是否重連、重連間隔、redirect地址等) | |
增加可擴充套件能力 |
Payload format and content type |
豐富訊息格式,使用者更友好 |
Message expiry |
業務層也可以自己做,協議層原生支援更優雅 | |
Subscription ID |
客戶端可以建立訂閱識別符號與訊息處理程式的對映,提高客戶端topic匹配速度 | |
Will delay |
類似疲勞度策略,一定時間內,裝置如果重連成功,則不發遺囑。 | |
Server Keep Alive |
服務端可以根據自身負載情況,動態調整max keepalive,實現動態keepalive | |
Assigned ClientID |
支援雲端給裝置生成clientId | |
Server reference |
1.跟http location類似 2.接入層支援切流和排程會更加靈活,不用再依賴DNS | |
User properties |
給業務層提供極高的可擴充套件性 | |
提高系統的伸縮性 |
Session expiry |
便於快速重連場景下client對clean session的使用和管理 |
Shared Subscriptions |
南向類似裝置廣播,北向類似服務端訂閱 | |
Optional Server feature availability |
支援端-雲能力協商 | |
最佳化資源受限和小客戶端接入 |
Subscription options |
提供更細粒度的訂閱策略,例如裝置側來決定是否允許自發自收 |
Topic Alias |
類似hpack,減少頻寬開銷 | |
Flow control |
裝置側可配置的傳輸策略,可根據自身資源情況,靈活指定訊息傳輸限制 | |
Maximum Packet Size | ||
No retry for QoS 1 and 2 messages |
最佳化QoS1 訊息重試策略 | |
常見正規化下沉至協議層 |
Request / Response |
user properties即可支援,broker不感知 |
Enhanced authentication |
支援增強認證(例如支援Kerberos 認證、SCRAM認證) |
1) 使用者屬性
裝置上下行訊息的時候支援攜帶使用者自定義的屬性,使用者可以新增兩端約定的屬性資料,類似於MQ的標籤,其中雲端在轉發應用訊息時會保持所有使用者屬性的先後順序。
2) 主題別名
裝置上報訊息的topic常常相對比較固定,數量不會特別多,那麼只需首次傳送訊息的時候,透過攜帶Topic別名告知對端, 下次傳送訊息的時候,這個topic將會使用這個Topic別名的值來代替,即可減少上報Publish訊息的報頭。 透過將主題縮減為一個整型的數值可以達到減小MQTT報頭大小的作用,從而減小傳輸流量開銷,非常適用於頻寬資源受限的裝置。
3)請求/響應模式
MQTT3.1版本中通訊雙方需要事先協商好請求主題和響應topic。 MQTT5 新增了響應主題和相關資料,接收方只需關注怎麼處理請求,而不用事先協商或考慮好怎麼將響應正確返回給請求方。
4) 響應報文原因碼和原因字串
mqtt 3.1協議中原因碼的種類較少,這些原因碼所能表示的含義很少,並且mqtt3.1不支援服務端透過disconnect報文斷開連線,導致裝置端僅根據響應難以定位問題。 mqtt5.0有近50個原因碼,絕大部分ack響應報文都包含了原因碼,裝置可以根據這些豐富的原因碼定位請求是否成功以及問題。 MQTT5議能反饋更多的錯誤資訊到端上,並且支援雲端透過disconnect報文主動斷開連線, 裝置端知道服務端發生了什麼,因而能更靈活的應對。
5) 服務端能力協商
支援告知裝置端 雲端所支援的功能列表,避免裝置端使用雲端不支援的功能。
1.3 業內現狀
1.3.1 開源社群 & 雲產商
- 目前主流MQTT Broker開源社群基本已經支援v5.0,並且開源SDK也已經初步支援v5.0,與此同時,國內IoT雲廠商還沒有支援v5.0,但未來已來。
1.3.2 客戶端SDK支援現狀
2. MQTT協議層實踐
2.1 MQTT應用架構
主要分為6大模組:
- 基礎接入模組:包括多版本協議編解碼、多協議埠複用、會話管理、心跳檢測、連線管理等。
- 協議擴充套件模組:包括基於自定義協議擴充套件,實現的一系列擴充套件功能,包括通道解壓縮、低功耗免ping等。
- 增值訊息服務:包括Rrpc、廣播、時鐘同步、指令碼前置解析等。
- 業務埋點模組:裝置行為統計、線上時長聚合、網路延時診斷等。
- 安全防禦模組:包括黑名單機制、入口流控等。
- 高可用模組:包括流量分組排程、容災降級等。
- 運維管控模組:主要包括流量分組排程、限流管理、連線診斷
2.2 協議層設計挑戰
- 裝置狀態一致性策略設計,包括session管理機制、心跳檢測機制、異地登陸問題、狀態最終一致性策略。
- 在MQTT釋出/訂閱非同步分發模型上,如何滿足多樣的業務場景。例如同步呼叫、廣播等。
- 如何同時滿足不同場景下裝置對MQTT接入需求,單應用上如何同時支援兩個版本MQTT協議
- MQTTv3協議過於精簡,業務從MQTT3切換到v5的過渡時間,如何擴充套件協議層能力,提高客戶接入體驗。
2.3 MQTT關鍵策略設計
2.3.1 裝置線上狀態
協議層本地有session管理器來對本地會話進行管理,透過心跳檢測、會話自檢來保證跟裝置之間的連線狀態一致性,當前平臺單裝置不支援同時同裝置多端登陸,基於分散式會話,協議層透過分散式會話識別異地登陸,將異常連線踢下線。
裝置狀態一致性策略:裝置到MQTT協議接入層之間是tcp長連線,透過心跳機制保證心跳週期內裝置狀態的最終一致性。同時透過分散式會話版本號,保證分散式會話併發更新安全,透過上行訊息/心跳定時觸發會話自檢機制,解決異常情況下本地/分散式會話狀態不一致的問題。
2.3.2 訊息推送模式
MQTT協議是基於PUB/SUB的非同步通訊模式,針對單裝置緯度實現基礎的釋出/訂閱推送外,還支援了複雜的訊息推送方式:RRpc和線上廣播。
在傳統的基於PUB/SUB通訊模式的中介軟體中, 訊息的Producer/Consumer只負責生產和消費,彼此之間不會直接通訊。 而在某些業務場景不僅僅是將訊息投遞至訂閱方,訂閱方收到訊息後可能還會執行一些操作並返回結果,PUB/SUB模式下實現這種請求/響應模式會非常繁瑣,在MQTT中通訊雙方需要事先協商請求和響應topic。
針對這一痛點,協議層在釋出訂閱模式之上構建了一套Rpc通訊模式,解決開發者痛點。Rrpc模式允許Producer發出訊息後,以同步形式等待Consumer消費這條訊息並返回響應,達到類似Rpc的呼叫效果。Rrpc模式使得MQTT應用具備了同步呼叫的能力,擴充套件了使用場景,使其具備更多的可能性。
- 透過topic中包含的messageId匹配請求與響應,對業務資料零侵入
- messageId的生成與匹配、超時控制等邏輯,呼叫方無感知
- 簡化了業務方呼叫邏輯,擴充套件了MQTT使用場景。
2.3.3 多種類接入方式
MQTT協議層針對不同場景支援多種MQTT接入方式,同時支援tcp直連、tls、ws、wss等方式接入,用於滿足不同場景接入需求。為了實現更好的網路穿透性,協議層實現了多協議埠複用,也就是一個埠同時支援多種協議。
- 邊解析邊判斷,處理效率高;
- 節約常用埠,實現更好的網路穿透性
- 內部能力擴充套件對裝置側無感知
- 針對MQTT協議5和3,透過協議解析也實現了同時相容。
2.3.4 自定義協議擴充套件
MQTTv3在實際應用中存在一些缺點,而MQTTv5生態的繁榮推廣還需要很長時間的推進, 在MQTT3到5的過渡時間,我們在v3.1.1基礎上透過overlay的方式,提供了擴充套件套件來解決客戶痛點。
沒有什麼問題不是封一層解決不了的,如果有那就再封一層,思路:
- 透過在建連clientId中擴充套件ext引數,實現端雲之間能力協商
- 透過擴充套件訊息topic格式,實現支援自定義屬性
- 定義一套ext異常推送topic規範
環節 |
3.1協議擴充套件 |
5.0對標功能 |
帶來的增值能力 |
建連 |
能力協商 |
Broker能力發現 |
|
傳輸 |
Topic擴充套件引數 |
使用者屬性 |
|
離線 |
Ext系統Topic |
錯誤反饋 |
|
- 豐富接入增值能力,提高接入體驗
- 後端能力提前ready沉澱,5.0升級可複用已有能力
2.4 未來展望
當前阿里雲IoT平臺協議層已支援了MQTT主流協議,並支援了多種協議接入方式,但還存在一些會進一步最佳化的地方:1)更豐富的訊息質量模型,例如支援QoS2,支援訊息優先順序等; 2)完善低功耗領域的閘道器側支援,可以跟SDK/邊緣閘道器合作,支援MQTT-SN協議等
3. 參考資料
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70017009/viewspace-2911805/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MQTT協議實踐MQQT協議
- MQTT 協議 Keep Alive 詳解MQQT協議
- DDS協議解讀及測試開發實踐協議
- MQTT協議從服務端到客戶端詳解MQQT協議服務端客戶端
- MQTT協議(二)MQQT協議
- MQTT物聯網通訊協議入門及Demo實現MQQT協議
- 初識MQTT協議MQQT協議
- MQTT 協議 -- CONNECT & CONNACKMQQT協議
- FTP協議詳解FTP協議
- raft協議詳解Raft協議
- TCP協議詳解TCP協議
- Kraft協議詳解Raft協議
- VxLAN協議詳解協議
- HTTPS協議詳解HTTP協議
- Gossip 協議詳解Go協議
- USB協議詳解協議
- SPI協議詳解協議
- HTTP協議詳解HTTP協議
- QUIC協議詳解UI協議
- WebSocket 協議詳解Web協議
- UDP協議詳解UDP協議
- MQTT 協議是個啥?MQQT協議
- MQTT 協議快速體驗MQQT協議
- 詳解HTTP&HTTPS協議及面試題HTTP協議面試題
- HTTP協議和MQTT協議對比誰更好HTTP協議MQQT
- MQTT工作筆記0001---MQTT協議概述MQQT筆記協議
- MQTT協議簡介及百度雲物接入loT-MQTT測試MQQT協議
- http協議/cookie詳解/session詳解HTTP協議CookieSession
- 網路通訊協議-ICMP協議詳解!協議
- 網路通訊協議-TCP協議詳解!協議TCP
- 網路通訊協議-HTTP協議詳解!協議HTTP
- 網路通訊協議-SMTP協議詳解!協議
- 組播協議詳解協議
- HTTP 3協議詳解HTTP協議
- 19_MQTT協議介紹MQQT協議
- 輕量通訊協議 --- MQTT協議MQQT
- MQTT 協議中的 Keep Alive 。MQQT協議
- MQTT協議 - arduino ESP32 通過精靈一號 MQTT Broker 進行通訊的程式碼詳解MQQT協議UI