<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    聶永的博客

    記錄工作/學(xué)習(xí)的點點滴滴。

    MQTT 3.1協(xié)議非嚴(yán)肅反思錄

    前言

    MQTT 3.1協(xié)議在弱網(wǎng)絡(luò)環(huán)境下(比如2G/3G等)表現(xiàn)不夠好,因此才有了反思。

    弱網(wǎng)環(huán)境下表現(xiàn)

    手機等終端在弱網(wǎng)絡(luò)環(huán)境下丟包情況會非常明顯,連接MQTT Server成功率很低。相比單純的請求-相應(yīng)模型的HTTP,其成功率會比MQTT訂閱成功高很多。

    手機終端在每次TCP斷開或斷網(wǎng)后,會即刻發(fā)起TCP重連,連接成功,會重復(fù)以前步驟依次發(fā)送連接命令(CONNECT),訂閱命令(SUBSCRIBLE),表明上看,這些過程沒有任何問題,但問題就在于從終端成功建立到服務(wù)器的連接,到發(fā)送訂閱命令,在弱網(wǎng)情況下,這個過程將會變得很昂貴:

    從TCP建立開始的三次握手到完整的訂閱命令發(fā)送完畢,考慮到TCP堆棧的每次接收數(shù)據(jù)方響應(yīng)ACK,這中間終端和服務(wù)器端至少產(chǎn)生了10次數(shù)據(jù)交互。
    

    在網(wǎng)絡(luò)變化頻繁或者不太穩(wěn)定的2G/3G網(wǎng)絡(luò)環(huán)境下,這種過程顯得有些冗長和不適應(yīng),同時會加重已經(jīng)不堪的弱網(wǎng)絡(luò)負(fù)載的負(fù)擔(dān)。

    弱網(wǎng)下,在任何一個階段的執(zhí)行過程中,都有可能產(chǎn)生突發(fā)性的網(wǎng)絡(luò)中斷的問題:

    1. 無法成功建立TCP鏈接,或死在三次握手期間,或數(shù)據(jù)包丟失在握手之后,或客戶端連接超時過小

    2. 建立連接后,發(fā)送CONNECT命令后,或沒接收到TCP ACK確認(rèn)包,或客戶端等待延時太小,導(dǎo)致訂閱命令交互失敗

    3. 發(fā)送SUBSCRIBLE命令后,但服務(wù)器端沒收到,或因為丟包,或網(wǎng)絡(luò)已斷開,導(dǎo)致發(fā)送SUBSCRIBLE命令失敗

    4. 成功發(fā)送SUBSCRIBLE命令后,或移動網(wǎng)絡(luò)斷開了(有些運營商針對認(rèn)為HTTP的請求有超時判斷),或等待超時,導(dǎo)致訂閱失敗

    TCP是無感知的虛擬連接,中間斷開兩端不會立刻得到通知,否則就用不著心跳保活機制了。

    舉一個例子,線上的服務(wù)器根據(jù)日志分析,只接收到連接命令(CONNECT)但沒有后續(xù)的訂閱命令(SUBSCRIBLE)的情況,每天有上百萬級別的數(shù)量。

    總之,針對低速率弱網(wǎng)絡(luò)環(huán)境,MQTT表現(xiàn)不怎么好。

    改進(jìn)點

    業(yè)務(wù)改進(jìn)點:

    1. 客戶端的連接超時、等待超時設(shè)大一點,兩秒太短,可設(shè)置長一些,比如10秒
    2. 服務(wù)器端支持在接收到用戶發(fā)送CONNECT命令后,瞬間發(fā)送一些live data/hot data(早已緩存的數(shù)據(jù)),類似于HTTP請求-相應(yīng)模型,目的嘛,一些熱數(shù)據(jù)發(fā)送給終端要趁早,越快越好(所謂出名要趁早嘛);這個需要客戶端、服務(wù)器端同時支持

    協(xié)議改進(jìn)點:

    1. CONNECT命令可變頭部包含"MQisdp"太多余了,學(xué)院派風(fēng)格嘛
    2. 允許在連接命令中負(fù)載(payload)中攜帶訂閱Topic字符串
    3. 允許在連接命令中表示上次連接訂閱的Topic發(fā)生變化否,攜帶訂閱業(yè)務(wù),雖冗余,但實用。 eg:訂閱的Topic沒有發(fā)生變化,TOPICCHANGE:0;退訂,UNSUBSCRIBE:TOPICONE;SUBSCRIBE:TOPIC_TWO
    4. PUBLISH、PUBACK等支持的 Message Identifier 才16位,太短,實際業(yè)務(wù)無法做到全局唯一。引入mid和業(yè)務(wù)id的映射對應(yīng)關(guān)系?那是狀態(tài),需要維護(hù),代價還是蠻高的。業(yè)界流行看法,無狀態(tài)化的架構(gòu)才是便于橫向、豎向、縱向、四方向的擴展,呵呵。最好方式就是修改使之支持字符串形式,否則維護(hù)代價高!
    5. 心跳命令PINGREQ/PINGREQ可以做到一個字節(jié)傳輸,節(jié)省一個字節(jié),有些強迫癥的感覺嘛
    6. 低速率網(wǎng)絡(luò)需要做一些兼容和調(diào)整

    有些建議看似冗余,批量或打包處理總比單個處理更高效一些、更節(jié)省資源,弱網(wǎng)絡(luò)環(huán)境要求交互要盡可能的少,數(shù)據(jù)嘛要的是瞬間抵達(dá),越快越好。

    嚴(yán)格的分層和業(yè)務(wù)解耦,會導(dǎo)致性能問題。好比當(dāng)前Linux內(nèi)核的TCP/IP網(wǎng)絡(luò)堆棧分層很清晰,每一層都各司其職,但和直接略過內(nèi)核態(tài)直接運行在用戶態(tài)(User Space)的Packet I/O相比,處理性能不是在一個檔次上,比如Netmap 、DPDK等。

    MQTT-SN

    針對沒有TCP/IP等網(wǎng)絡(luò)堆棧支持的終端環(huán)境,MQTT愛莫能助了。

    在一些類似于傳感器電子元件中,資源十分受限,計算能力不足,嵌入TCP/IP網(wǎng)絡(luò)堆棧不現(xiàn)實,比較好的方式基于IEEE 802.15.4用于低速無線個人域網(wǎng)(LR-WPAN)的物理層和媒體接入控制層規(guī)范之上發(fā)送UDP數(shù)據(jù)包,每一個數(shù)據(jù)包最大128個字節(jié)。

    MQTT-SN(MQTT For Sensor Networks)協(xié)議就是為了非常受限類似傳感器而設(shè)的,協(xié)議流程架構(gòu)比較有趣:

    Image

    更多協(xié)議細(xì)節(jié),有待進(jìn)一步閱讀。

    TCP不是最適合的移動網(wǎng)絡(luò)傳輸協(xié)議

    先來算一下網(wǎng)絡(luò)傳輸?shù)淖止?jié)數(shù)。

    以太網(wǎng)幀頭至少18個字節(jié),IP頭固定20個字節(jié),TCP頭20個字節(jié)(UDP頭部8個字節(jié)),再加上電信寬帶計費的PPPoE的8個字節(jié):

    • TCP數(shù)據(jù)包頭部信息至少占有66個字節(jié)
    • UDP數(shù)據(jù)報頭部信息至少占有54個字節(jié)

    UDP可以比TCP節(jié)省12個字節(jié)。

    MQTT-SN協(xié)議選擇使用UDP,可以看出其在節(jié)省資源方面的努力。

    再看看弱網(wǎng)環(huán)境。

    • 在網(wǎng)絡(luò)可達(dá)情況下,UDP可以在TCP建立第一次握手期間就已經(jīng)把數(shù)據(jù)送達(dá)目的地
    • 完成三次握手期間,UDP客戶端和UDP服務(wù)器在數(shù)據(jù)層面可以完成一次完整的交互(PING-PONG)

    在網(wǎng)絡(luò)不好的情況下,UDP的時效性會好于TCP,TCP長連接中間交換過多、使之建立完整交互的過程成功率就很低。此種情況UDP的低延遲和實時性呈現(xiàn)的結(jié)果會表現(xiàn)的很突出。

    TCP或HTTP理論上是可靠連接,但是在網(wǎng)絡(luò)不好的時候,也不是那么可靠。客戶端一般提交HTTP請求之后,沒有確認(rèn)是否提交成功,在弱網(wǎng)環(huán)境下會產(chǎn)生丟包,服務(wù)器端嘛收不到。另TCP網(wǎng)絡(luò)堆棧會存在數(shù)據(jù)包重發(fā)機制 + 應(yīng)用層重發(fā)請求,可能會導(dǎo)致內(nèi)核處理多次數(shù)據(jù)包的重發(fā)(還有擁塞窗口會收縮,發(fā)包速度減慢),可能會加重弱網(wǎng)絡(luò)的負(fù)載。

    和TCP相比,UDP的無連接,代表了它快速,資源消耗小,突出表現(xiàn)就是延遲較小。至于數(shù)據(jù)包丟失沒有重傳,上層的業(yè)務(wù)層面應(yīng)用協(xié)議/機制可以確保丟失的數(shù)據(jù)包重發(fā)或補發(fā)等,并且會更透明,安全的控性權(quán)。而TCP的包重發(fā),上層應(yīng)用沒有控制權(quán)限。

    連接協(xié)議方面:

    • TCP面向連接會產(chǎn)生狀態(tài)管理和維護(hù),成本不小,比如經(jīng)常看到的客戶端reset異常等。一次完整的請求周期必須固定在一臺服務(wù)器上
    • UDP無連接的特性。每次請求的數(shù)據(jù)包可以隨機分配到不同的機器上進(jìn)行處理,可以做到完全無狀態(tài)化橫向擴展

    總之,要實時性特診,或者快速抵達(dá)終端的特性,不妨考慮一下UDP。不過呢,很多時候UDP和TCP大家會混合著使用,會互相彌補其不足。

    小結(jié)

    若MQTT協(xié)議不能夠滿足業(yè)務(wù)需求,或許可考慮選擇定制,或簡化流程,或使用UDP重新實現(xiàn),或者使用TCP/HTTP作為補充等,不一而足。

    想想,還真有點小激動呢! ------ 《萬萬沒想到》王大錘

    posted on 2014-12-12 10:19 nieyong 閱讀(31302) 評論(17)  編輯  收藏 所屬分類: MQTT

    評論

    # re: MQTT 3.1協(xié)議非嚴(yán)肅反思錄 2014-12-16 17:20 tangsir

    你好,謝謝你的文章。
    我們有個手機APP,目前的方案是實時數(shù)據(jù)直接socket連接(不好的地方是客戶端服務(wù)端都要寫代碼),想全面轉(zhuǎn)向mqtt(這樣服務(wù)端就專注于從mqtt對立里面獲取數(shù)據(jù),進(jìn)行業(yè)務(wù)處理,并發(fā)送消息即可),邏輯上應(yīng)該更清楚,代碼開發(fā)也方便。但是聽你這個介紹有點猶豫了,要不要改呢?請聽你的指教!  回復(fù)  更多評論   

    # re: MQTT 3.1協(xié)議非嚴(yán)肅反思錄 2014-12-17 10:25 nieyong

    @tangsir
    目前除了MQTT,暫時找不到比它更好的業(yè)界標(biāo)準(zhǔn)了。建議選擇MQTT 3.1.1協(xié)議:
    支持客戶端在發(fā)送完畢CONNECT之后,無須等待服務(wù)器響應(yīng)直接發(fā)送其余命令
    支持服務(wù)器和客戶端兩端暫時會話保存,上次連接之后,再次CONNECT,會話標(biāo)志位true,可無須發(fā)送SUBSCRIBLE命令
    具體請參考:
    MQTT 3.1.1,值得升級的6個新特性  回復(fù)  更多評論   

    # re: MQTT 3.1協(xié)議非嚴(yán)肅反思錄 2014-12-17 23:21 tangsir

    謝大神!@nieyong
      回復(fù)  更多評論   

    # re: MQTT 3.1協(xié)議非嚴(yán)肅反思錄 2014-12-18 22:06 nieyong

    @tangsir
    措辭有問題,可不是什么大神,呵呵。
    只是總結(jié)而已。  回復(fù)  更多評論   

    # Bad Piggies Game 2014-12-19 15:55 Bad Piggies Game

    措辭有問題,可不是什么大神,呵呵。  回復(fù)  更多評論   

    # Jogos Frin 2014-12-22 11:55 friv4school2015@hotmail.com

    措辭有問題,可不是什么大神,呵呵。  回復(fù)  更多評論   

    # Jogos Frin 2014-12-22 11:55 friv4school2015@hotmail.com

    措辭有問題,可不是什么大神,呵呵。   回復(fù)  更多評論   

    # Friv School 2015 2014-12-25 11:07 yepimatasa

    措辭有問題,可不是什么大神,呵呵  回復(fù)  更多評論   

    # re: MQTT 3.1協(xié)議非嚴(yán)肅反思錄 2015-05-07 21:33 kdm

    你好我們有手機設(shè)備也有硬件設(shè)備,不同的設(shè)備需要根據(jù)不同的情況推送各自的數(shù)據(jù),如果我們有10萬個終端,我們需要建立10萬個topic嗎?有沒有其它地方法謝謝?  回復(fù)  更多評論   

    # re: MQTT 3.1協(xié)議非嚴(yán)肅反思錄 2015-05-08 09:49 nieyong

    @kdm
    其實,靈活一點是不需要建立10W個topic的,根據(jù)clientId就可以  回復(fù)  更多評論   

    # re: MQTT 3.1協(xié)議非嚴(yán)肅反思錄 2015-05-14 21:53 kdm

    @nieyong
    請教一下根據(jù)clientId如何做,請大神指導(dǎo)  回復(fù)  更多評論   

    # re: MQTT 3.1協(xié)議非嚴(yán)肅反思錄 2015-05-15 10:04 nieyong

    @kdm
    clientId等同于topic就行  回復(fù)  更多評論   

    # re: MQTT 3.1協(xié)議非嚴(yán)肅反思錄 2015-05-15 17:45 kdm

    @nieyong
    那還是每個設(shè)備一個topic對吧。topic的主題為clientId.  回復(fù)  更多評論   

    # re: MQTT 3.1協(xié)議非嚴(yán)肅反思錄 2015-05-18 16:41 nieyong

    @kdm
    是的,比如根據(jù)協(xié)議,只需要注冊一次,服務(wù)器端可持久化topic和clientId的對應(yīng)關(guān)系,后面不需要再次注冊等。或者再簡單一些,就直接根據(jù)clientId作為topic就行。

    怎么說呢,越是海量用戶/終端的系統(tǒng),協(xié)議交互層面需要越簡單,架構(gòu)層面也是如此。  回復(fù)  更多評論   

    # re: MQTT 3.1協(xié)議非嚴(yán)肅反思錄 2015-06-12 13:56 Justin Gao

    看了這篇文章,實話說有點不以為然

    本文說了半天,就是一個問題,當(dāng)subscribe命令在交互時候出現(xiàn)問題怎么辦?

    回到協(xié)議本身,事實上是很簡單的一個答案,只有收到正確的suback命令才能認(rèn)為subscribe成功,否則客戶端有義務(wù)不斷地重復(fù)發(fā)送subscribe。

    而判斷正確返回否則管理著重發(fā)的機制本來就是message queue的精髓所在,在客戶端維護(hù)一個最基礎(chǔ)記錄subscribe的queue,原始意義上并不是特別難。

    至于本文所提的用UDP協(xié)議,或者和改造協(xié)議部分,重傳部分?jǐn)?shù)據(jù)的方法,只會使協(xié)議復(fù)雜度變高很多,出錯可能性增加;在高并發(fā)的環(huán)境中,并不可取。而相對來說,客戶端做更改難度小很多。  回復(fù)  更多評論   

    # re: MQTT 3.1協(xié)議非嚴(yán)肅反思錄 2015-09-13 09:32 mqtt

    subscribe讓服務(wù)器自動訂閱,把客戶端subscribe功能禁止掉  回復(fù)  更多評論   

    # re: MQTT 3.1協(xié)議非嚴(yán)肅反思錄 2016-05-23 07:34 Jammers

    This is very nice. Thank you.  回復(fù)  更多評論   

    公告

    所有文章皆為原創(chuàng),若轉(zhuǎn)載請標(biāo)明出處,謝謝~

    新浪微博,歡迎關(guān)注:

    導(dǎo)航

    <2014年12月>
    30123456
    78910111213
    14151617181920
    21222324252627
    28293031123
    45678910

    統(tǒng)計

    常用鏈接

    留言簿(58)

    隨筆分類(130)

    隨筆檔案(151)

    個人收藏

    最新隨筆

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲国产一级在线观看| 亚洲理论片在线中文字幕| 日本不卡免费新一区二区三区 | 亚洲一级大黄大色毛片| 国产成人在线观看免费网站| 成全视成人免费观看在线看| 亚洲成人福利在线观看| 免费一看一级毛片人| 91精品免费不卡在线观看| 亚洲av纯肉无码精品动漫| 亚洲精品无码久久久影院相关影片 | 一二三四视频在线观看中文版免费| 色九月亚洲综合网| 亚洲日本中文字幕区| 夜夜嘿视频免费看| 国产高清不卡免费视频| 亚洲AV香蕉一区区二区三区| 亚洲成AV人片一区二区密柚| 日韩毛片免费在线观看| 91精品免费不卡在线观看| 和老外3p爽粗大免费视频| 亚洲av日韩av综合| 国产亚洲一区二区三区在线观看| 大学生高清一级毛片免费| 久久er国产精品免费观看2| 国产成人+综合亚洲+天堂| 99ri精品国产亚洲| 精品亚洲成α人无码成α在线观看 | 91嫩草免费国产永久入口| eeuss免费影院| 亚洲成av人无码亚洲成av人| 亚洲欧洲日产国码在线观看| 国产国拍精品亚洲AV片| 国产精品免费视频一区| 最近最新的免费中文字幕| 免费无码VA一区二区三区| a级精品九九九大片免费看| 日韩电影免费在线观看网址| 亚洲熟妇av午夜无码不卡| 亚洲国产成人久久综合一区| 亚洲成a人片在线观看日本|