MQTT v3.1.1 與 v5 完全相容,且提供許多Cluster 所需要的功能,如Shared Subscriptions、 User Properties等實用功能,且不會因為新增加功能造成效能低落的問題。
MQTT 起初是由 IBM 在 1999 年提出的,是針對 IoT 裝置設計的 MQ,是屬於發展許久的 MQ。主要設計的原則是:
雖然起出被設計用於 IoT (Internet of Thing) 裝置,但目前MQ被廣泛運用在Platform因此在2019 年時MQTT正式提出v5版本更被推薦,主要就是為了platform 平台新的需求新增加功能。(目前市面上有兩個版本,v3.1.1、v.5) MQTT Architecture
MQTT v3.1.1 Features
在功能面MQTT 是以 v3.1.1作為基礎的功能,而v5則是為雲服務進行擴充但也更改一些特性,如QoS...。MQTT與傳統意義有些許不一樣。如下比較表:
MQTT | TraditionalMQ | |
---|---|---|
Persistent Message | 當consumer 取的訊息之前,可設定將訊息保存在MQ中,直到被取用 | 當consumer 取的訊息之前,可設定將訊息保存在MQ中,直到被取用 |
Distribution Ability | 透過Topic的方式可很輕鬆的進行傳遞給多個consumer | 傳統的consumer與queue是一對一的綁定,不太能分享訊息 |
Queue Name | 使用上完全不用理會name 是否衝突的問題,只要在乎想訂閱的Topic | 須自行管理queue 的name |
MQTT v3.1.1主要功能有QoS、Topic、Persistent Session(重新連線後Topic還存在)、Retained Messages、Last Will。
代表的是發送與接收訊息的品質,可設定0-2這個區間。
MQTT Topic是由utf-8 編碼組成,如Http的URL的概念,透過"/"進行分階層。如下圖,myhome階層下groundfloor、livingroom、temperature等,如同REST 架構中對於URI的規範類似。
2.1 Topic 特殊符號:
當clinet 對MQTT 連線斷掉時,Topic 將會自動的discard。但為了解決這個問題,Persistent Serssion的設計就是為了解決這個問題而生。
有效時broker 存取的東西:
Persistent Session使用方式
就是在連線的時候需要將option的clean session 設定為false。
主要是在producer上的功能,發送訊息後會將訊息保持在Topic 上,使的新的加入者也可以獲取最新的息。若在沒有設定的情況下,新加入的consumer不會收到上一個以發送過的訊息。
是在producer上的功能,當Producer斷線的時候,可指定lwt的Topic,與想要傳送的訊息。這功能主要用來debug用的,官方提供這種功能很適合放在上online and offline 的管理上。
在這個版本中整體使用方式,MQTT v5與v3.1.1之間功能上的的差別在於 QoS 1 以上不再重傳訊息、retained messages、persistent sessions不再支援了。
類似http header 的概念,可以在每一個訊息上加入一個property header ,consumer 端可依賴該欄位進行運用。Broker 根據consumer 所訂閱的設定進行訊息routing。
在v5的版本中,原生支援load balance的功能,consumer 可在建立連線的時候設定Broker shared選項綁定多個consumer 成為一個群組。
在Intel i7 9750H、16GB RAM在Docker 環境下測試,其中使用 eclipse-mosquitto:2.0.11 Image 作為MQTT broker。由於MQTT v5的版本在Open Source 社群上並未完整支援,以Eclipse MQTT 社群為例,目前完整支援MQTT v5的只有Java、Python、C/C++等三種。
但實際使用Java、Python 發現並未完全支援,只有C語言有完整支援,如下圖所示。因此在實驗的部份採用Mosquitto 所提供的mosquitto_pub 作為Publisher;使用npm 平台的mqtt v4.2.6版本作為Subscriber進行實做。由於Nodejs該模組在publish 的部份,會因Nodejs中的Event 排程受到影響,因此只使用Subscriber 功能。
實驗分為兩種測試,吞吐量測試(TPS)、精準度測試(QoS)。吞吐量測試分為Publisher與Subscriber 兩種角色,在_Publisher 的配置以1、3、5、7、10 個Publisher 進行測試;Subscriber 同 Publisher ,分成1、3、5、7、10 個 Subscriber的場景配置,將發送100萬個封包計算平均每秒的吞吐量。精準度測試的部份,配置分成1、3、5、7、10 個 Subscriber_與1個 Publisher進行測試,將發送100萬個訊息,平均計算每個Subscriber收到的數量。
當Publisher 增加時,Publisher TPS 明顯的下降,但Subscriber TPS 則線性成整且QoS不變,代表著mosquitto不會因為封包數量變大,造成不一樣的Qos。換句話說Client (Publisher) 之間並不會互相影響Subscriber所收集到的資訊。
當Subscriber 增加時,Publisher TPS 並沒有什麼改變,且Subscriber TPS、QoS也不變,代表著mosquitto不會因為封包數量變大,造成不一樣的Qos。換句話說Client (Subscriber)之間並不會互相影響。
在Publisher當一次傳輸的封包變少時,TPS、QoS 會以指數的方式成長。一次的數量超過極限的吞吐量,則會造成Subscriber QoS下降,因為mosquitto 預設機制為當QoS > 0時,broker內部給單一個Client的內存queue封包數量為1000條訊息。因此只要超過一定的吞吐量會造成QoS降低。同時訊息數量大,會造成壅塞的情形,使Publisher、Subscriber 的 TPS 受到影響。
Subscriber 與 Publisher 都以QoS 為2的狀態下盡情測試,mosquitto 以預設值進行量測。發現MQTT v3.11、v5 並未有明顯差異,且v5的效能些微比v3來的弱一點。且透過上述實驗可得到以下幾點結論:
MQTT v3.1.1、 v5效能並未有大的差異,且v5的版本提供更多的功能。雖然官方文件上所述QoS的實作方面有受到調整,但經過測試後並未有大的差異,但市場上的所提供的工具目前很少,相信未來MQTT v5的版本是比v3.1.1來的更好更實用的。