MQTT主題在MQTT生態系統非常重要,因為代理(broker)依賴主題確定哪個客戶端接收指定的主題。本文我們將聚集MQTT主題、MQTT通配符,詳細討論使用它們的最佳實踐,也會探究SYS主題,提供給代理(broker)本身的見解。
什么是MQTT主題及它們在消息過濾中的角色?
在MQTT中,主題,代理一個UTF-8編碼的字符串,為連接的客戶端過濾消息。一個主題由一或多個斜杠分割的層級組成。
和消息隊列相比,MQTT主題是非常輕量級的。客戶端在發布或訂閱之前不需要創建期望的主題。代理(broker)接受合法的主題,不需要提前初始化。
MQTT主題例子
下面是一些MQTT主題例子:
- myhome/groundfloor/livingroom/temperature:這個主題代表一個家庭第一層起居室的溫度。
- USA/California/San Francisco/Silicon Valley:此主題層級結構可以跟蹤或交換與美國加得福尼亞舊金山的硅谷區域相關的事件或數據信息。
- 5ff4afdad-d324-fdaf-dfas-f2jaddjfjtd/status:這個主題可以用來監控一個被唯一標識符指定的設備或系統的狀態。
- Germany/Bavaria/car/34935932/latitude:此主題結構可用于共享德國巴伐利亞地區特定汽車的緯度坐標。
使用MQTT主題的最佳實踐
下面是一些使用MQTT主題的最佳實踐:
- 每個主題必須包含至少一個字符。
- 主題字符串可以包括空格,以允許更具可讀性或描述性的主題。
- 主題是大小寫敏感的,意味著“myhome/temperature”和“MyHome/Temperature”是兩個不同的主題。
- 斜杠本身就是一個有效的主題,可用于表示廣泛的主題或用作同時訂閱多個主題的通配符。
MQTT主題是MQTT代理(broker)和客戶端建立通信的關鍵。依據主題內容,能夠有效過濾和路由消息。在基于MQTT的系統中,確保高效交換、處理數據,合適的定義、組織主題至關重要。
MQTT通配符及主題訂閱中如何使用
在MQTT中,通配符提供了一種有力的機制來同時訂閱多個主題。當一個客戶端訂閱一個主題,它即可以訂閱已發布消息的確切的主題,也可以使用通配符來擴展它的訂閱。要注意的是,通配符只能用在訂閱上,而不能用在發布消息上。有兩類通配符:單層級和多層級。
單層級通配符:+
單層級通配符由+號表示,允許替換單個主題層級。通過訂閱一個使用單層級通配符的主題,將匹配任何包含任意字符串代替通配符的主題。
比如,一個“myhome/groundfloor/+/temperature”的訂閱能產生以下結果:
多層級通配符:#
多層級通配符覆蓋多個主題層級,由#號表示,必須放在主題字符的最后,前面有一個斜杠。
當一個客戶端訂閱了使用多層級通配符的主題時,它會接收以通配符之前的模式開頭的主題的所有消息,無論主題的長度和深度。如果主題只有單獨的“#”,則該客戶端接收所有代理(broker)發送的消息。
但是,重要的是要考慮到,如果期望高吞吐量,僅使用一個“#”進行訂閱可能是一種反模式。訂閱一個寬泛的主題會導致大量的消息被發送到客戶端,潛在的影響系統性能和帶寬使用。遵循優化主題訂閱最佳實踐,避免不必要的消息負載。
為什么及何時使用$開頭的主題
在MQTT中,主題命名靈活性很廣,允許你選擇符合需要的任何名稱。但是,有一個重要的例外需要注意:以$符號開頭的主題有專門的目的。使用多層級通配符(#)作為主題時,這些主題(以$開頭的)不包括在訂閱中。相反,以$開頭的主題保留用于MQTT代理(broker)的內部統計信息。
發布消息到以$開頭的主題是不被允許的,因為這些主題用來提供一些途徑給MQTT代理(broker)來暴露內部信息和統計給客戶端。但是,現在這些主題沒有官方標準,通常使用前綴$SYS/來表示此類信息,盡管代理(broker)的具體實現可能有所不同。
MQTT GitHub wiki中提供了用于理解$SYS主題的推薦資源。
下面是一些$SYS主題的例子和這些主題能夠提供的信息:
- $SYS/broker/clients/connected:指示當前連接到MQTT代理(broker)客戶端的數量。
- $SYS/broker/clients/disconnected:顯示從MQTT代理(broker)已斷開連接的客戶端數量。
- $SYS/broker/clients/total:代表所有和MQTT代理(broker)交互的客戶端的數量,包括連接的和斷開連接的。
- $SYS/broker/messages:提供MQTT代理(broker)發送的所有消息的數量。
- $SYS/broker/uptime:反映了MQTT代理(broker)持續運行的時間。
這些$SYS主題提供了有關MQTT代理(broker)內部工作和性能的寶貴信息,使管理員和開發人員能夠監控和分析關鍵統計信息。
通過理解以$開頭主題的目的和意義,就可以有效的更深入的了解MQTT基礎設施的行為和性能。
探究MQTT主題的動態性質
這些是MQTT主題的基礎,正如能看到的,MQTT主題是動態的,提供了很好的靈活性。當在現實應用中使用通配符時,有一些挑戰要注意。在重多廣泛使用MQTT的項目中,我們已經收集了請多最佳實踐。
MQTT最佳實踐
避免斜杠開頭
雖然MQTT允許主題以斜杠開頭(如何/myhome/groundfloor/temperature),但引入了一個不必要的主題級別,前面是一個零字符。會導致歧義,而沒有任何好處。所以,建議排除斜杠開頭。
在MQTT主題中不要使用空格
空格是每個程序員的天然敵人,主題中的空格可能會妨礙可讀性和調度,特別是在異常處理場景中。另外,UTF-8有許多不同的空格類型。在MQTT主題中,建議抵制使用空格和其他不常用在字符。
保持MQTT主題簡明扼要
記住,每個主題都被包含在使用它的每條消息中。為了優化網絡流量并節省寶貴資源,請使主題盡可能簡明扼要。在資源有限的設備中,會顯得特別重要,每個字節都被計算其中。
只使用ASCII字符,避免使用不可打印字符
為了確保主題的連貫性和明確性,建議使用ASCII字符。非ASCII的UTF-8字符可能會顯示異常,使識別拼寫錯誤或字符集相關總是變得難以處理。除非必要,在你的MQTT主題中避免使用非ASCII字符。
在主題里嵌入一個唯一標識符或客戶端ID
要增強消息標識并強制執行授權,考慮在主題中嵌入發布客戶端的唯一標識或客戶端ID。這樣,允許你確定消息的發送方,控制發布的權限。例如,有client1 ID的客戶端能夠發布消息到client1/status,而不是client2/status.
避免訂閱通配符#
有時候,訂閱所有通過代理(broker)的消息是有必要有。比如,為了將所有消息持久到數據庫。不要使用MQTT客戶端訂閱代理(broker)上的所有消息并訂閱多層級通配符。通常情況下,訂閱的客戶端無法處理所有消息的負載(尤其是在吞吐量很大的情況下)。
擁抱可擴展性
MQTT主題提供天然的靈活性,允許將來的擴展和新功能。考慮如何設計主題的結構能夠適應未來的擴展或新增傳感器或新增功能。設計主題以提高擴展性,而無需大幅更改整體主題層次結構。比如,如果你的智能家居方案增加了新的傳感器,添加這些到你的主題樹,而無需修改整體主題的層級,應該是可能的。
使用明確的主題,而不是能用的
區別你的主題來反映特定的數據流或實體。避免嘗試用一個主題代表多個類型的消息。比如,在你的起居室有三個傳感器,創建主題myhome/livingroom/temperatur,myhome/livingroom/brightness,myhome/livingroom/humidity,而不是使用一個類似myhome/livingroom的主題。這種做法提高了清晰度,并允許使用高級的MQTT功能,比如保留消息。后面文章中會詳細介紹。
文檔化
維護詳細說明MQTT主題的文檔,包括它們的目的、期望的消息負載和任何相關的約定和指導。有有助于擴展新的團隊成員,有利于更好的合作。
持續改進
根據需求的改進、MQTT系統的反饋,經常檢查、優化主題的結構。擁抱持續改進心態以確保高效且可擴展的MQTT通信。
安全
確保的你主題名稱和命名約定不會無意間泄漏敏感信息。應用合適的接入控制和認證機制來保護MQTT通信。
結論
在MQTT傳輸消息中,MQTT主題是高效性和靈活性的基石。通過理解其復雜性和最佳實踐,可以優化MQTT應用,為了最大化性能和擴展。
整篇文章,探究了MQTT主題的動態特性,深入通配符的使用、技術注意事項。討論了避免使用斜杠開頭和空格在主題中的重要性,使用ASCII字符和嵌入唯一標識符或客戶端ID。同樣強調了不要使用通配符訂閱所有的消息的重要性,在主題設計中擴展性的意義。
遵循這些最佳實踐,可以增加MQTT基礎設施的可讀性、可維護性和安全性。
接下來的文章中,會深入了解QoS