移動端IM系統的協議選型:UDP仍是TCP?

一、前言

圖片描述

對於有過網絡編程經驗的開發者來講,使用何種數據傳輸層協議來實現數據的通訊,是個很是基礎的問題,它涉及到你的第一行代碼該如何編寫。html

從PC時代的IM開始,IM開發者就在爲數據傳輸協議的選型爭論不休(好比:《爲何QQ用的是UDP協議而不是TCP協議?》這樣的問題,隔一段時間就能在社區裏看到)。到了移動互聯網時代,鑑於移動網絡的不可靠性等特色,再加上手機的省電策略、流量壓縮等,爲這個問題的回答增了更多的不肯定因素。git

對於有選擇困難證的人來講,基於以上因素,加上UDP和TCP協議的本質差別,這樣的選擇確實很糾結。本文將從做者的實踐總結,給出自已的觀點,若有異議還請理性回覆,不爲找噴,僅供參考。編程

說明:本文引用了DDPush的技術資料,感謝原做者。 (本文同步發佈於:http://www.52im.net/thread-33...安全

二、學習交流

三、參考資料

爲何QQ用的是UDP協議而不是TCP協議?網絡

UDP中一個包的大小最大能多大併發

基於TCP協議的移動端IM仍然須要心跳保活機制框架

NAT詳解:基本原理、穿越技術(P2P打洞)、端口老化等運維

計算機網絡通信協議關係圖(中文珍藏版)

理論經典:TCP協議的3次握手與4次揮手過程詳解

微信對網絡影響的技術試驗及分析(論文全文)

四、UDP vs TCP

TCP仍是UDP?長鏈接如何實現?如何實現心跳機制?心跳的間隔如何肯定?這些問題都是討論移動端IM、消息推送等相似話題時,幾乎必定被問到的問題。這裏嘗試正本清源一下。

五、互聯網、移動互聯網網絡環境

在分析到底應該使用UDP仍是TCP以前,有必要先討論一下互聯網與移動互聯網的網絡環境特色。

互聯網的網絡基礎建設,通過十幾年長期的發展,已經較爲穩定和成熟,PC終端、操做系統的能力也達到了較高的水平。

而移動互聯網,因爲涉及到無線電話網絡基站、2G、3G和4G技術的不斷髮展,其穩定性、帶寬、資源分配等各方面雖日趨完善,但當前終究還有很多問題的存在。另外,因爲移動互聯網其「移動」的本質,加上智能終端設備(智能手機、平板電腦)的發展較晚,目前還在不斷演變的狀況,與互聯網相比,移動互聯網仍是低速、不穩定、終端能力稍弱的狀況。並且因爲其「移動」本質,短期內很難達到互聯網的質量。

因此,在互聯網的環境裏面,網絡應用程序因爲網絡設施、操做系統的成熟,開發使用起來比較容易,資源也較爲充足。而移動互聯網仍是要「斤斤計較」。

六、智能終端電池續航能力,系統休眠

智能終端設備的電池續航能力始終是技術瓶頸。在連續使用的狀況下,絕大部分智能設備電池沒法支持兩個小時以上。因此在沒有外部電源的狀況,智能終端設備必須頻繁、長時間休眠,這將極大地影響兩種網絡環境下的網絡應用場景。

七、IPv4資源、端口資源

這個話題每每被不少人忽略,但它有着相當重要的影響。雖然大部分人都很清楚IP地址的緊缺致使的動態IP分配的必然,卻忽略了因爲IP地址不足引發的端口資源不足。

因爲須要動態分配IP地址(這裏不只僅指互聯網入口的IP,還包括局域網內部的IP),路由器的工做原理都是通過端口映射,把內部網絡(包括PC、手機、平板、Wifi、2G、3G、4G)IP與端口映射成外部IP(一般是公網IP)和對應的端口,並維持這個映射關係,才能正常地修改、轉發報文信息,保證內部各個ip、端口與外部的各個ip、端口的通訊。

然而,單個IP地址的端口資源是有限的,理論上限是65535個端口。對於普通寬帶路由器來講,這個已經很充足了。可是!對於大型的網絡服務、網絡主幹接入點等來講,若是IP資源不足,每一個IP幾萬個端口的資源很快會耗盡,從而影響正常通信。(有關NAT技術原理,請參見《NAT詳解:基本原理、穿越技術(P2P打洞)、端口老化等》)

八、端口映射老化時間

正由於如此,全部的路由器都會爲每一個端口映射關係設置老化時間,若是老化時間倒數到0,則端口映射關係失效,該端口被釋放給其餘鏈接使用。若是端口所有耗盡,則沒法再新建內部與外部的網絡鏈接。

端口映射老化時間,比不少人想象中的要短不少。通常的家用寬帶路由器,老化時間通常是兩三分鐘;在有線寬帶運營商接入部分,老化時間可能少於兩分鐘。在無線電話網絡運營商接入部分(例如GPRS鏈接),老化時間甚至不超過一分鐘!

也就是說,任何一個網絡通信(無論是TCP或UDP),若是幾分鐘以內沒有網絡報文傳輸,其佔用的IP地址端口將被路由器回收。這個時候該次通訊必將終止,無論TCP仍是UDP,神馬都是浮雲。

更殘酷的事實是,互聯網可認爲是由無數個路由器鏈接而成的,一個網絡通訊每每須要經過n個路由器,每一個路由器都會爲一次通訊創建本身的端口映射。只要其中一個路由器回收其端口,則整個通信中斷。

這也是不少人疑惑爲何TCP的KeepAlive參數沒法保證長鏈接的緣由。TCP的KeepAlive默認是兩個小時(並且該參數仍是TCP的可選實現,不是必然實現),在路由器端口映射老化時間的影響下,必然沒法發揮其做用。實際上,該參數在單一的局域網內纔可能被使用上,還要依賴具體的操做系統。

因爲路由器端口映射的存在,加上智能終端頻繁、長時間的休眠,TCP長鏈接的實用性在移動互聯網狀況下極大地打了折扣。

也由於如此,移動端IM、推送系統必須實現所謂的心跳包機制,以保持端口映射關係的老化時間不會減小到0而被回收,從而避免鏈接中斷。(有關TCP協議下的心跳問題,請參見:《基於TCP協議的移動端IM仍然須要心跳保活機制》)

九、服務端承載能力

無論是UDP仍是TCP,最終都是應用服務端的設備去提供服務的。而TCP因爲提供了安全可靠的流服務,其對計算機、網絡資源的消耗是遠遠大於UDP協議的。對於配置較好的主流服務器,配備大量的內存(數十G至上百G內存),與高速的磁盤、網卡,是能同時支持數百萬個TCP鏈接的。不過這裏須要較專業的服務器設置,須要調整很多系統參數,再加上服務程序的配合。另外,TCP鏈接的創建、維持與釋放,都是須要較昂貴的計算、網絡資源的。

終端在線服務,如果一個較爲簡單的服務,未必使用上TCP衆多的高級功能,但承受TCP的昂貴成本,未必值得。若是能用UDP來提供服務,單服務器的承載能力,是能夠去到TCP服務的數十倍,甚至上百倍的增加。這也是爲何DNS這種併發數巨大的服務器提供UDP接口的緣由。

另外,上百萬TCP鏈接的網絡服務,其編程的難度、程序複雜度、調試難度、服務器運維成本、網絡成本等都遠遠高於UDP。

而UDP編程,與上百萬個終端通信的難度與成本則低不少。若是提供的網絡服務不是基於流的服務,也容許必定的失敗機率(例如P2P),則UDP每每是更適合的方式。

十、高級應用網絡通信要求

不過,移動端IM系統、推送系統一方面提供終端在線服務,另一方面也須要考慮內容信息的完整性和安全性。畢竟信息的丟失,或者通信的被竊聽,都是難以接受的。而TCP無論在網絡層的可靠性控制,仍是在應用層的安全支持(例如HTTPS),都爲應用提供沒法替代的強大功能和便利。

十一、結論

綜合以上所述,其實答案也呼之欲出。

如今的移動端IM、推送系統,既面對移動互聯網的不肯定性,又面對智能終端頻繁的系統休眠、網絡切換,還要考慮服務端的承載成本,對於在線服務而言UDP是比TCP更適合的方式。可是因爲數據完整性、安全性的須要,又不該徹底放棄TCP的可靠與安全。

因此,我的認爲,更恰當的方式應該是:兩種通訊協議同時使用,各有側重。UDP用於保持大量終端的在線與控制,應用與業務則經過TCP去實現。這個和FTP服務控制與數據分離,採起不一樣的鏈接,有殊途同歸之處。

事實上,這個也是即時通信巨頭QQ所採用的方式。早期的時候,QQ仍是主要使用TCP協議,然後來就轉向了採用UDP的方式來保持在線,TCP的方式來上傳和下載數據。如今,UDP是QQ的默認工做方式,表現良好。相信這個也被沿用到了微信上。

簡單的考證:登陸PC版QQ,關閉多餘的QQ窗口只留下主窗口,並將其最小化。幾分鐘事後,查看系統網絡鏈接,會發現QQ進程已不保有任何TCP鏈接,但有UDP網絡活動。這時在發送聊天信息,或者打開其餘窗口和功能,將發現QQ進程會啓用TCP鏈接。

(本文同步發佈於:http://www.52im.net/thread-33...

做者:Jack Jiang(點擊做者姓名進入Github)

出處:http://www.52im.net/space-uid...

交流:歡迎加入即時通信開發交流羣215891622

討論:http://www.52im.net/

Jack Jiang同時是【原創Java Swing外觀工程BeautyEye】和【輕量級移動端即時通信框架MobileIMSDK】的做者,可前往下載交流。

相關文章
相關標籤/搜索