趙 靖,王如武,周 皓
大連理工大學 軟件學院,遼寧 大連 116024
隨著“工業互聯網”“工業4.0““中國制造2025”等戰略的提出,制造業數字化轉型已成為共識。打破不同工業系統間的信息壁壘,改善傳統工業企業的“信息孤島”現象,整合海量數據,挖掘更大的信息價值,優化流程,提升效率,賦能工業生產、管理、運營、銷售、售后等整條生態鏈,是數字化轉型的目標和作用。工業制造往往涉及的產品類型眾多,工業系統之間千差萬別,而且工業現場環境復雜,網絡不穩定。盡管在降低時延方面,可以采用目前比較流行的邊緣計算解決方案,在工廠內部或附近放置大量邊緣云設備以減少延遲,但大量的專有傳感器及邊緣設備的信息交互也會增加通信成本,加大工業用電量,增加成本和運營費用。因此通訊協議的選取至關重要,而在物聯網領域廣泛流行的消息隊列遙測傳輸(Message Queuing Telemetry Transport,MQTT)[1]協議就因為其消息體積小,通訊成本低,能量消耗少,適合在結構各異的系統間進行消息傳遞而備受關注。其獨特的發布/訂閱體系結構,使不同客戶端之間的通信脫鉤,從而允許不同的供應商在不同的系統中獨立實現MQTT,擺脫原始系統本身的專有協議進行通信,從而在不同的專有系統中建立互操作性,非常適合作為工業生產中多種異構系統與部件間消息傳遞的標準,在智能制造中的應用越來越受歡迎。國內外的工業互聯網平臺,如華為FusionPlant平臺、西門子mindsphere平臺、海爾COSMOPlat平臺等的解決方案中都采用了MQTT作為通訊協議,因此在傳統工業企業中通過部署MQTT進行大量設備間的消息傳遞已經逐漸成為一種普遍的選擇。
而在MQTT部署方案的制定中以及實際部署前,若先通過仿真模擬技術獲取關鍵數據以供參考,并且快速得到直觀的部署效果從而及時修正,則可以大大減小方案落地后的偏差,降低試錯成本。這得益于仿真的簡便靈活,可以快速獲取所需數據(如網絡設備吞吐量、網絡帶寬、時延等),而且成本極低,這對于工業企業來說是至關重要的。如果初期就通過實際部署進行評估測試會造成大量人力物力財力的浪費。
模擬部署MQTT是觀察及研究其性能和表現的重要手段。目前在該方面主要分為小規模本地部署和仿真軟件模擬兩種方式。文獻[3]中通過在兩臺機器上分別搭建單獨的MQTT客戶端和服務端進行了小規模的模擬實驗,對比了MQTT和CoAP兩種協議的端到端時延和帶寬消耗情況,結果表明協議的性能取決于網絡條件,在較低丟包率時MQTT會具有更低的延遲,但是該實驗只設置了一個客戶端,對于大量客戶端的情況無法進行準確評估。文獻[4]利用OPNET仿真器進行無線樓宇網絡中MQTT的仿真以獲取最佳部署節點數,然后在實際系統中部署進行下一步測試。雖然其能夠較好地模擬MQTT,但是OPNET并不是免費的軟件,主要面向商業用戶,價格昂貴。文獻[5]中使用OMNet++仿真器的INET框架評估了MQTT協議在工業環境下的性能,觀察了在不同傳感器數量下該協議的吞吐量和時延變化。但是文獻[6-7]中的對比結果都表明,相比于OMNet++等其他模擬器,NS-3模擬器都有著更好的整體性能,比如需要更少的計算時間及更低的內存,同時NS-3是開源免費的,它擁有更加活躍的社區對其進行維護,每三到四個月定期發布具有新功能的版本[8]。另外,利用文獻[9]提供的ns3-ai擴展模塊還可以開展計算機網絡和人工智能算法相結合的交叉研究,這些優勢都促使更多的人愿意使用NS-3,并積極地完善和擴展它以便進行更廣泛的研究。
本文針對NS-3中無法對MQTT協議提供簡單易用的模塊和接口支持問題,提出并實現了一個名為ns3-mqtt的框架來對NS-3進行擴展,詳細描述了該框架的設計策略和實現細節,包括它的三個擴展組件(MQTT核心模塊、MQTT應用程序、MQTT幫助程序),同時提供了一個工業場景仿真案例來說明集成后的NS-3如何模擬部署MQTT以獲取必要數據,進而為實際部署MQTT提供有力的幫助。另外,還對數據包大小和客戶端數量對MQTT協議性能的影響進行了研究,觀察到了和OMNet++仿真器中相似的現象,證明了ns3-mqtt框架的可行性。
NS-3網絡模擬器是一個開源的離散事件驅動的網絡模擬器,主要用于研究和教育目的[10]。它可以在一臺計算機上用C++和Python編寫腳本來模擬現實世界的網絡[11]。在一個網絡系統的仿真中,每一個實體都會由一個稱為節點的容器表示。網絡設備、協議、應用程序都會依次安裝到這個容器中。NS-3提供了多種網絡協議(802.11、TCP、UDP等)及通訊技術(WIFI、LTE、5G等),作為一個開源項目,它完全由C++語言編寫,主要運行于linux平臺,任何組織和個人可對源碼進行下載及修改,由NS-3社區維護。另外,它還可以與外部系統和實際應用進行交互,提供了與其他平臺進行聯合仿真并獲取更真實數據的可能性。
MQTT協議是一種使用發布/訂閱機制的消息傳遞協議,最初由Andy等設計[12],適用于資源受限設備以及低帶寬、高延遲或不可靠的網絡[13]。該協議位于OSI網絡模型中的應用層,依賴于傳輸層的TCP協議以及網絡層的IP協議,支持TLS/SSL加密。它獨特的消息傳遞機制以及低帶寬占用、可靠的特性,使其非常適合工業領域云邊通信[14]的應用場景,在有限帶寬的情況下也可為大量傳感器等設備的連接提供實時可靠的消息服務。該協議基于一個稱為broker的中心服務器來實現對所有消息的代理,形成發布訂閱模式,其客戶端只能夠和中心服務器直接交互,而且消息的傳遞是基于主題的,客戶端可向某一主題發布訂閱請求或發布請求,中心服務器一旦接收到消息請求,就會根據消息主題在該主題的訂閱列表下增加該客戶端以滿足訂閱請求,或者分發消息內容給已訂閱該主題的其他客戶端以滿足發布請求,可實現訂閱方和發布方之間的解耦。
1.2.1 MQTT協議的消息格式
MQTT消息由2個字節的固定報頭,2個字節的可變報頭以及有效載荷三部分組成,固定報頭的格式規范如圖1所示。其中Retain字段用于設置該條消息是否需要服務端保留;Qos Level字段用于設置該條消息所需的服務等級;Dup Flag字段用于設置該條消息是否為重發消息;Message Type字段的值代表消息的類型(共有14種);Remaining Length字段的值則代表消息的可變報頭和有效載荷大小。

圖1 MQTT固定報頭格式Fig.1 MQTT fixed header format
可變報頭是否存在由消息類型(Message Type)決定,當消息類型為PUBLISH(Qos>0)、PUBACK、PUBREC、PUBREL、PUBCOMP、SUBSCRIBE、SUBACK、UNSUBSCRIBE、UNSUBACK類型時可變報頭存儲的是報文標識(MessageID),長度為2個字節,其他類型時可不添加可變報頭。而有效載荷則承載了MQTT消息攜帶的實際數據,包括主題和內容。
1.2.2 MQTT協議的主題
MQTT協議的主題Topic起到過濾消息的作用,同時也是消息的一種標識,從而對消息進行分組。客戶端只會收到其感興趣的分組的內容。它是一個分層結構,在表示上類似restful風格。一個主題名可以由多個主題層級組成,每一層通過“/”斜杠分隔開,例如:“/layer1/layer2/layer3“。如果客戶端對多個相似分組感興趣,則可以在主題的某個層級使用通配符,包括“+”和“#”兩種。“+”通配符屬于單層通配符,只匹配某一個層級的全部內容,例如“/layer1/+”可匹配“/layer1/layer2a”和“/layer1/layer2b”。而“#”屬于多層通配符,可匹配包括當前層級在內的后面的全部層級的子主題。需要注意的是“#”通配符也可代表0個層次,比如“/layer1/#”也能匹配單一的“/layer1”,此時“#”就代表0個層級。同時它在一個主題只能出現一次,且需在主題層級的末尾處,不可以出現在主題的中間和首部,也不可以在多個層級中同時出現。
1.2.3 MQTT協議的消息服務質量
MQTT協議通過控制Qos等級來決定服務質量[15],其Qos等級共有三個,分別是Qos0、Qos1、Qos2。不同的等級代表了不同的可靠性要求,具體描述如下。
(1)消息服務等級為Qos0時,代表著消息到達至多一次,由于消息發布是完全依賴于底層的TCP/IP協議的,因此會有消息丟失或重復的情況發生。這一等級的服務適用于偶爾丟失一次記錄無影響的場景下,比如監測環境溫度信息,它會在不久以后繼續接收下一次消息。
(2)消息服務等級為Qos1時,代表著消息至少到達一次,但是可能會有消息重復現象發生。
(3)消息服務等級為Qos2時,代表著消息一定會到達且只到達一次。這一等級適用于對消息重復或者丟失比較敏感的場景。
ns3-mqtt框架由MQTT核心模塊、MQTT應用程序、MQTT幫助程序三個部分組成。MQTT核心模塊主要實現了協議頭、客戶端和代理服務端。代理服務端可對消息進行存儲和轉發、客戶端可訂閱和發布消息,二者均支持Qos0、Qos1、Qos2三種服務等級。考慮到未來對保留消息功能的潛在需求,例如測試新訂閱客戶端獲取歷史消息的性能等,還實現了對Retain類型消息的支持。而MQTT應用程序部分則是在MQTT核心模塊基礎上開發,分為mqtt-client和mqtt-broker兩個應用程序,能夠定時開啟和關閉客戶端以及服務端,并進行端到端的數據統計。同時能夠通過設置客戶端發包大小、間隔、Qos等進行流量生成。另外還編寫了ns3::mqttbroker-helper和ns3::mqtt-client-helper類作為幫助程序,該部分的目的是提供便捷的高度封裝的接口,并可以批量安裝MQTT應用程序以及靈活設置流量生成參數,為安裝和使用MQTT應用程序提供方便。圖2展示了ns3-mqtt框架的結構以及和NS-3自身模塊間的關系。

圖2 ns3-mqtt框架結構Fig.2 ns3-mqtt frame structure
該模塊參考MQTT-V3.1.1[1]協議規范對MQTT協議主要功能進行了實現。模塊結構遵循NS-3項目風格。圖3顯示了模塊中所有類之間的關系。其中ns3::Mqtt-Header類是基于ns3::Header類的擴展,ns3::util類則是用于對MQTT頭部數據的存取操作進行簡化。同時,服務端和客戶端由ns3::broker類和ns3::client類實現,二者采用packet對象作為信息載體,利用TCP/IP協議提供的可編程接口socket[16]實現通訊,其中服務端類還要依賴ns3::mqtt_db類進行數據管理。以下各節將對實現細節進行詳細解釋。

圖3 MQTT核心模塊類關系圖Fig.3 MQTT core module class diagram
2.1.1 MQTT消息頭
MQTT協議消息頭由名為MqttHeader的類表示。根據NS-3官方文檔所述,該類必須從ns3::Header類派生,并實現ns3::Header類的純虛方法。派生出的ns3::MqttHeader類需實現MQTT協議頭部的序列化和反序列化,而序列化或反序列化中每次操作的字節數則需根據協議本身進行設置。為方便數據統計和重發數據包的辨別,將MQTT的可變頭部統一設置為2個字節。因此MQTT協議報文頭固定為4個字節。相對應的ns3::MqttHeader類里序列化和反序列化函數中每次操作的大小也為4個字節。需要注意的是,序列化和反序列化過程會調用Buffer函數對緩沖區進行寫入和讀出,二者的調用順序不能顛倒,否則會造成緩沖區數據異常。另外,在ns3::packet中添加MQTT消息頭需調用其中的AddHeader函數。由于ns3::MqttHeader中數值以二進制形式存儲,因此需通過位運算將協議頭部各字段值寫入。而接收方獲取數據包后則需利用ns3::packet中提供的PeekHeader函數,將數據先取出到ns3::MqttHeader對象中,然后調用該對象中GetData函數才能獲取到數據。此數據為32位(4個字節)的二進制數,最后還需通過特定的位運算才能獲取協議報文各字段的值,比如Message Type,Qos等。表1列出了協議頭部二進制數據的寫入和讀出涉及的位運算公式。其中d表示當前頭部的值。為了方便在程序中使用,已在輔助類中將其封裝成函數,提供了對應接口。

表1 字段計算公式表Table 1 Field calculation formula table
2.1.2 MQTT協議的客戶端
MQTT協議客戶端由ns3::client類實現,主要完成對消息的發送,三種Qos服務等級的交互響應以及客戶端參數的設置。消息的發送采用socket實現,Qos等級的交互響應采用回調函數和仿真調度器實現,具體的將在3.3.4小節進行介紹。ns3::client類提供的可設置參數有訂閱的主題、發送消息的類型和內容、Qos服務等級以及是否為保留消息,該類中默認接收消息的監聽端口號設置為1883。由于該類繼承自ns3::Application類,其可作為一種應用程序在Node上運行。但為了簡化仿真的復雜性,還提供了進一步封裝的客戶端應用程序mqtt-client,能夠較為簡便地對單一客戶端進行參數設置,例如數據流量參數等。而mqtt-client-helper幫助程序則是提供對客戶端批量安裝以及參數批量設定的功能,以適應更大規模的仿真,免去了仿真中需逐一安裝設定的麻煩。關于客戶端應用程序和幫助程序會在3.2、3.3節進行更詳細的介紹。
2.1.3 MQTT協議的服務端
MQTT服務端也稱為broker,它由ns3::mqtt_db,ns3::broker類實現。ns3::mqtt_db類負責存儲消息以及維護客戶端和消息之間的對應關系,ns3::broker類則負責數據包的接收校驗以及消息的轉發。并且ns3::mqtt_db和ns3::broker是一一對應的,前者作為后者類中的一個私有成員變量。
ns3::mqtt_db中存儲消息采用的數據結構是訂閱樹,它類似于多叉樹。樹的節點由Subtree_node對象表示,該對象由兩個分別存儲子節點指針和客戶端指針的列表,以及代表該節點名稱的字符串組成。其中客戶端可存儲在一個或多個樹節點下,代表該客戶端訂閱了由根節點的兒子節點到該節點途徑所有節點的名稱構成的主題,一個典型的訂閱樹如圖4所示,其中client2就訂閱了“/layer1/layer2a”和“/sys”兩個主題。ns3::mqtt_db在接收到經過ns3::broker校驗后的數據包時,首先會調用getPacketHeadType函數得到數據包包頭中的Message Type的值判斷消息類型,若是PUBLISH型消息,則用字符分割函數將負載中主題和內容分開,利用find_topic_exits函數對訂閱樹進行深度優先遍歷,判斷該主題在訂閱樹中是否存在,若存在,將會立即調用pub_add_sub_client函數以及push_msg_to_client函數將消息存儲在訂閱了該主題的客戶端中,這里的客戶端是一個臨時的Client對象,僅用作存儲消息內容和維護實際客戶端待接收的消息隊列,此時消息還未開始向實際客戶端發送。若是SUBSCRIBE型消息,則先調用find_child函數在訂閱樹中查找匹配的節點,此函數采用遞歸查找并返回可匹配到的最后一個節點。若能完全匹配則調用sub_add_sub_client函數將此訂閱客戶端存儲到完全匹配的最后一個節點的客戶端隊列中,準備接收消息。否則會先調用add_subtree_topic函數在訂閱樹中增加相應節點以達到完全匹配。

圖4 訂閱樹示例Fig.4 Example of subscription tree
ns3::broker類對接收到的數據包的包頭和負載進行校驗時,先通過位運算獲取其頭部各字段的值,若未出現非法值則校驗后該消息交由mqtt_db處理,否則丟棄該數據包。當消息經mqtt_db處理后,ns3::broker會對mqtt_db中訂閱樹進行搜索。若發現某個節點中Client的實際客戶端待接收消息隊列大小不為0,就根據Client的地址(和實際客戶端地址一一對應)取出消息隊列中的每一條消息。取出后隨即創建新的socket,根據Client的地址以及監聽的端口號(1883)與對應客戶端進行連接并轉發對應消息。該轉發功能同樣支持Qos的三個服務等級,但服務等級是由消息發布時的Qos等級和客戶端訂閱時的Qos等級共同確定,取二者的較小值。
2.1.4 MQTT協議的服務等級
MQTT協議的三種Qos服務等級功能的實現主要依靠回調函數和Simulator調度器,NS-3中的回調函數和C++中回調函數類似,都需要訂閱函數指針、賦值以及調用三個步驟。不過NS-3中對回調函數的步驟進行了簡化,其使用步驟被封裝在了對應的類和函數中。函數指針在Callback類模板中被定義,該模板可支持最多9個形參并可以定義函數簽名的返回值。而Callback對象的創建和賦值由函數MakeCallback完成。通過回調函數接收到消息時可以通過socket回復消息,但只能回復一次。接收者如果想要再次發送消息,只能構造新的socket來發送,這種情況多出現在Qos2等級中,因為需要完成兩次交互。Simulator調度器主要應用在控制何時去發送回復消息,該調度器是NS-3離散事件仿真引擎的入口,控制著整個仿真事件的調度,保證仿真不混亂。
在實際實現中只需設置MQTT數據包包頭的Qos Level字段即可將Qos值跟隨消息一起發送。其中Qos0等級由于只發送一次,故不存在交互行為。當服務等級為Qos1時,客戶端發送消息后會調用等待接收ack函數sendRecvAck來接收服務端發回的ack報文。同時此函數中設有等待時間,若在規定時間內沒有收到ack則重傳消息。當服務等級為Qos2時,客戶端發送消息后會調用sendRecvREC函數,等待接收PUBREC類型消息,若在規定時間無回應則重發該消息。若接收到PUBREC類型消息則開始進行第二次交互,也就是調用sendREL函數發送PUBREL消息,之后調用sendRecvCOMP函數等待服務端PUBCOMP類型的回應消息,若一段時間內收不到回應同樣會重傳消息,若接收到則代表著兩次交互已完成。在交互的過程中服務端會一直啟用socket監聽,收到消息后立即調用回調函數對消息進行解析和邏輯處理,由此來完成和客戶端的交互。而對于服務端轉發消息給客戶端的情況,同樣涉及Qos服務等級。這里Qos等級的確定方法和客戶端發送消息給服務端時相同,并且交互過程也相同,只是此時客戶端和服務端角色互換了。
2.1.5 MQTT協議的Retain功能
MQTT協議的Retain功能旨在讓新訂閱者及時得到發布方最新的消息或狀態信息。只要客戶端一訂閱帶保留消息的主題,就會立即獲得該主題下最新的保留消息。如果訂閱的主題帶有通配符,那么就會收到相匹配的每個主題下的保留消息。具體的設計思路為,對于服務端來說每個主題僅會保留唯一一個Retain消息,存儲在該主題尾部對應的訂閱樹節點的retainmsg成員變量中,新的Retain消息會不斷覆蓋之前的。如果想刪除某主題下的Retain消息,可以發布相同主題的,Retain字段為1并且內容為“-”的消息來刪除。實際實現中,服務端收到消息后會先將其存儲在訂閱樹中匹配的節點里,在節點處理待發數據時,遇到保留消息會存儲到retainmsg中。節點數據發送完畢就會清空待發數據隊列。待新的訂閱者到來時,如果其訂閱的主題對應的節點中retainmsg不為空,則將其中的保留消息發送給新的訂閱者(客戶端),使新訂閱者立即獲得該主題下最新的消息。
MQTT應用程序主要包括客戶端應用程序以及服務端應用程序,分別由類ns3::MqttClient和類ns3::MqttBroker實現。客戶端應用程序主要負責MQTT流量生成,可以設置的參數包括數據包大小、總數、發包間隔、發送速率、數據包中攜帶的主題和內容、數據包中攜帶的消息是否為保留消息以及發送所需的服務質量Qos(默認為Qos0)。而服務端應用程序可設置時間進行定時打開和關閉,在關閉后將調用Count函數進行數據統計并將結果輸出到控制臺或指定文件中。為方便進行延遲等數據的統計,在MQTT數據包中還添加了時間戳TimestampTag,但是NS-3中計算packet大小時會自動忽略TimestampTag對象的大小。表2、表3分別列出了服務端和客戶端應用程序的主要函數及說明。

表2 服務端應用程序函數列表Table 2 Server application function list

表3 客戶端應用程序函數列表Table 3 Client application function list
MQTT幫助程序主要目的在于提供更加簡便的高級接口,表4列出了這些高級接口。它們為節點批量安裝MQTT應用程序和設置屬性提供方便。該部分包括MQTT客戶端以及服務端兩個幫助程序,分別由類ns3::MqttClientHelper和類ns3::MqttBrokerHelper實現。二者均提供了Install方法用于在節點中簡便地安裝應用程序,同時提供兩種不同的安裝方式(由傳入的參數決定),分為單獨安裝和批量安裝。單獨安裝可對某一節點的應用程序單獨進行屬性設置,而批量安裝則會針對列表內所有節點統一安裝屬性相同的應用程序。

表4 MQTT幫助程序接口列表Table 4 MQTT helper interface list
本文選擇ns-3.30版本的NS-3為例說明擴展的軟件包如何安裝到NS-3仿真平臺中。NS-3的安裝環境為ubuntu18.04 Linux操作系統,內核版本為5.4.0-73-generic。具體的集成方法如下。
(1)下載ns-3.30版本的NS-3軟件。
(2)參照NS-3官方文檔安裝成功后,切換到ns-allinone-3.30/ns-3.30/src目錄,在該目錄下打開終端,輸入sudo./create-module.py ns3-mqtt命令,利用create-module.py腳本創建一個新的ns3-mqtt模塊。
(3)模塊創建完成后,進入ns-allinone-3.30/ns-3.30/src/ns3-mqtt目錄,也就是新創建模塊的文件夾中,用所擴展的ns3-mqtt軟件包里的文件替換這個文件夾下的所有文件。
(4)然后返回至ns-allinone-3.30/ns-3.30目錄下執行sudo./waf configure命令,對NS-3進行重新配置,編譯系統會檢查NS-3依賴的軟件包是否已經成功安裝。
(5)最后在相同目錄下執行sudo./waf命令進行編譯,編譯無錯誤則ns3-mqtt安裝成功。
3.2.1 仿真設置
本文設計的仿真實驗旨在給出一個示例作為參考,同時檢驗框架實現的效果。為了和文獻[5]中使用OMNet++進行的仿真實驗結果進行對比,本文中的仿真參數配置盡量與其接近。實驗模擬的是工業場景下空氣狀況的監測,涉及溫濕度傳感器和紅外氣體傳感器,分別用于空氣溫濕度的監測和空氣污染物的檢測。空間設定在100 m×100 m的范圍內,節點的分布分為兩個區域,左側區域(60 m×100 m)代表了工業生產區域,右側區域(20 m×100 m)代表了工業數據監測區域,MQTT服務端應用程序安裝在坐標為(50,50)的中心位置節點(位于工業生產區域內),訂閱方MQTT客戶端應用程序安裝在右側工業數據監測區域的邊緣位置,用于收集傳感器發送的數據。其他發布方MQTT客戶端應用程序都安裝在左側工業生產區域的節點中,工業生產區域的節點分布采用ns3::UniformDiscPositionAllocator模型以恒定的密度隨機均勻地分布在以(30,50)坐標為圓心半徑30 m的圓型區域內,移動模型選擇的是隨機圓盤靜態分布模型,所有節點在圓盤范圍內隨機靜態分布,通過使用NetAnim動畫工具展示了該布局,圖5給出了該布局的一個網絡拓撲示例。另外仿真實驗中發布方客戶端設置為每隔5 s發送固定大小數據包以生成流量,同時所有模擬運行10次取平均值以增加可信度,每次模擬運行120 s。仿真實驗的節點數量選為{1,30,60,90,120,150,180,210,240,270,300,330,360,390,420},和文獻[5]中不同的原因在于為了觀察當更大數量節點存在時,吞吐量及延遲的表現,這也是以前的研究所忽略的地方(注意這里的節點數量是指作為發布方的節點的數量)。同時考慮到仿真設定的空氣監測場景不是延遲敏感型的,并且文獻[5]中的實驗也采用了無線通信,因此通信模型選擇了wifi無線模型,Qos設置為默認值0。仿真中的數據包大小設置為12字節以更好地符合傳感器等小型設備發包較小的特點,同時也增設了大小為120字節的數據包用于觀察數據包大小對吞吐量和延遲的影響。

圖5 網絡拓撲示例Fig.5 Example of network topology
3.2.2 性能指標
MQTT的性能評估指標采用的是平均時延和最大吞吐量。該性能指標對于設備的采購和網絡部署具有關鍵的指導作用。性能指標中沒有選擇平均吞吐量的原因在于平均吞吐量只能反映設備一般情況下的性能,而工業環境中有著更嚴格的要求,即使在流量最高峰時也需滿足服務需求,因此在工業環境下最大吞吐量更有意義,能更精確地指導服務器等設備的參數選擇。以下為兩個指標的具體描述。
(1)平均時延:所有分組(數據包)從源節點到達目標節點所花費的時間的平均值,單位為s。
(2)最大吞吐量:單位時間內節點接收的最大數據量(分組大小之和),單位為bit/s。
3.2.3 仿真結果及分析
仿真實驗總共分為兩組。第一組仿真實驗,數據包大小設置為12 Byte。觀察了客戶端數量對吞吐量和端到端延遲的影響,以獲取該仿真環境中每個服務端應服務的最佳客戶端數量。圖6顯示了隨著客戶端數量的變化吞吐量大小的改變。圖7則顯示了隨著客戶端數量的變化延遲的改變。仿真結果顯示吞吐量在客戶端數量增長的初期不斷大幅度上升,而到達一定數量后上升幅度驟降,甚至開始下降,這與文獻[5]中觀察到的現象極其相似。

圖6 吞吐量峰值隨客戶端數量的變化Fig.6 Peak throughput variation with number of clients

圖7 延遲隨客戶端數量的變化Fig.7 Latency variation with number of clients
具體來看,客戶端數量是達到210后吞吐量的增幅開始驟降,甚至出現了負增長。這說明初期在一定范圍內隨著節點數量的增多,數據流量增加,帶寬利用率提高,同時網絡中的沖突和丟包現象較少,導致吞吐量提高。但是隨著節點越來越多,網絡信道過度使用、數據包丟失、網絡沖突等現象就會發生。這在工業環境中往往是很不利的。為此在實際部署前應充分考慮每個服務端能服務的客戶端數量,在保證通訊質量和數據完整性前提下最大限度地提升其吞吐量,提高資源利用率,節約成本。同時,實驗表明延遲雖然整體會隨著節點數量的增加而不斷增加,但是在客戶端數量達到240后延遲的增幅會加大。這是由于網絡數據包逐漸增多,在一定范圍內只是輕微擁堵造成延遲小幅度增加,但隨著客戶端的數量越來越多,數據包也會越來越多,而網絡信道的容量是有限的,會發生嚴重擁堵沖突,并且接收方客戶端的接收數據的速率也是有上限的,會產生排隊時延等問題,因此在當前仿真場景下,每個服務端服務的發布方客戶端的最佳數量應為210左右。
第二組仿真實驗,則是觀察了不同數據包大小對訂閱方客戶端吞吐量和延遲變化的影響,以獲取相關啟發。針對吞吐量,實驗觀察的是其達到增量拐點時對應的客戶端數量,增量拐點指在該點以后吞吐量增量驟降的點。實驗設置兩種數據包大小,分別是12 Byte和120 Byte。增加的120 Byte數據包用作對比,除單次發包大小不同外,其他仿真參數均不變。為方便對比效果的展示,將120 Byte時的吞吐量增量數據除以10。這樣處理是考慮到數據包大小增加十倍后,吞吐量也增加十倍左右。圖8顯示了在不同數據包大小下吞吐量增量隨著客戶端數量增加的變化情況。
從圖8中可以觀察到,數據包大小為12 Byte時到達增量拐點對應的客戶端數量為210,而120 Byte時為150,隨著數據包的增大增量拐點提前了。這是因為數據包的增大會更容易導致網絡擁塞。因此想要同時高質量地服務更多的客戶端則需要更小的消息負載來降低數據包大小。

圖8 吞吐量增量隨客戶端數量的變化對比Fig.8 Comparison of throughput increment with number of clients
另外該組實驗也觀察到了數據包增大對端到端的延遲的影響,圖9顯示了不同數據包大小下延遲隨客戶端數量增加的變化情況。

圖9 延遲隨客戶端數量的變化對比Fig.9 Comparison of latency with number of clients
觀察圖9可以發現,在210個客戶端內,不同的負載下二者的延遲相差很少,但是隨著客戶端數量的繼續增加,更大的數據包就會導致更高的端到端的延遲。這是因為往往較大數據包被接收所需的時間更長,而在客戶端較少時由于接收方的收包能力是冗余的,單位時間內接收的數據量一直未到達極限值,因此對延遲的影響極小。從以上吞吐量增量和延遲的對比來看,較小的數據包都會帶來更優的性能。為此在實際部署MQTT時應盡量降低單次發送數據包的大小以獲取更好的性能及更低的部署成本。
本文提出了ns3-mqtt擴展框架,并以軟件包的形式集成到NS-3中,使得在NS-3中模擬部署MQTT成為可能,極大地方便了相關研究的展開。本文的框架設計思路以及協議的實現方法對NS-3中實現或改進其他應用層協議也具有借鑒意義,可供讀者參考。同時,為驗證框架實現的有效性,參照文獻[5]中使用OMNet++仿真器的仿真參數,在集成后的NS-3中進行了相似的仿真實驗。仿真結果表明該框架能夠在NS-3中按照預期運行,且觀察到了和文獻[5]中相似的實驗現象。下一步的工作主要集中在開發安全模塊,繼續豐富和擴展本文提出的框架,通過仿真分析一些新穎的MQTT安全增強方案,并探究進一步改進的方法。