探探的IM長連接技術實踐:技術選型、架構設計、性能優(yōu)化

本文由探探服務端高級技術專家張凱宏分享,原題“探探長鏈接項目的Go語言實踐”,因原文內容有較多錯誤,有修訂和改動。
1、引言
即時通信長連接服務處于網絡接入層,這個領域非常適合用Go語言發(fā)揮其多協(xié)程并行、異步IO的特點。
探探自長連接項目上線以后,對服務進行了多次優(yōu)化:GC從5ms降到100微秒(Go版本均為1.9以上),主要gRPC接口調用延時p999從300ms下降到5ms。在業(yè)內大多把目光聚焦于單機連接數的時候,我們則更聚焦于服務的SLA(服務可用性)。
本文將要分享的是陌生人社交應用探探的IM長連接模塊從技術選型到架構設計,再到性能優(yōu)化的整個技術實踐過程和經驗總結。

學習交流:
- 即時通訊/推送技術開發(fā)交流5群:215477170?[推薦]
- 移動端IM開發(fā)入門文章:《新手入門一篇就夠:從零開發(fā)移動端IM》
- 開源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK?
(本文已同步發(fā)布于:http://www.52im.net/thread-3780-1-1.html)
2、關于作者
?
張凱宏:擔任探探服務端高級技術專家。
6年Go語言開發(fā)經驗,曾用Go語言構建多個大型Web項目,其中涉及網絡庫、存儲服務、長連接服務等。專注于Go語言實踐、存儲服務研發(fā)及大數據場景下的Go語言深度優(yōu)化。
3、項目緣起
我們這個項目是2018年下半年開始,據今天大概1年半時間。
當時探探遇到一些技術痛點,最嚴重的就是嚴重依賴第三方Push,比如說第三方有一些故障的話,對實時IM聊天的KPS有比較大的影響。
當時通過push推送消息,應用內的push延時比較高,平均延時五六百毫秒,這個時間我們不能接受。? ?
而且也沒有一個 Ping Pland 機制(心跳檢查機制?),無法知道用戶是否在線。
當時產品和技術同學都覺得是機會搞一個長連接了。
4、一個小插曲
項目大概持續(xù)了一個季度時間,首先是拿IM業(yè)務落地,我們覺得長連接跟IM綁定比較緊密一些。
IM落地之后,后續(xù)長連接上線之后,各個業(yè)務比較依賴于長連接服務。
這中間有一個小插曲,主要是取名字那一塊。
項目之初給項目起名字叫Socket,看到socket比較親切,覺得它就是一個長連接,這個感覺比較莫名,不知道為什么。但運維提出了異議,覺得UDP也是Socket,我覺得UDP其實也可以做長連接。
運維提議叫Keepcom,這個是出自于Keep Alive實現(xiàn)的,這個提議還是挺不錯的,最后我們也是用了這個名字。
客戶端給的建議是Longlink,另外一個是LonGConn,一個是IOS端技術同事取的、一個是安卓端技術同事取的。
最后我們都敗了,運維同學勝了,運維同學覺得,如果名字定不下來就別上線的,最后我們妥協(xié)了。
5、為什么要做長連接?
為什么做長連接?
?
如上圖所示:看一下對比挺明顯,左邊是長連接,右邊是短長連接。
對于長連接來說,不需要重新進入連接,或者是釋放連接,一個X包只需要一個RTT就完事。右邊對于一個短連接需要三次握手發(fā)送一個push包,最后做揮手。
結論:如果發(fā)送N條消息的數據包,對于長連接是2+N次的RTT,對于短連接是3N次RTT,最后開啟Keep Alive,N是連接的個數。
6、長連接技術優(yōu)勢
我們決結了一下,長連接有以下四大優(yōu)勢:
1)實時性:長連接是雙向的通道,對消息的推送也是比較實時;
2)有狀態(tài):長連接本身維護用戶的狀態(tài),通過KeepAlive方式,確定用戶是否在線;
3)省流程:長連接比較省流量,可以做一些用戶自定義的數據壓縮,本身也可以省不少的歸屬包和連接包,所以說比較省流量;
4)更省電:減少網絡流量之后,能夠進一步降低移動客戶端的耗電。
7、TCP在移動端能勝任嗎?
在項目開始之前,我們做了比較多的考量。
首先我們看一下對于移動端的長連接來說,TCP協(xié)議是不是能夠Work?
對于傳統(tǒng)的長連接來說,Web端的長連接TCP可以勝任,在移動端來說TCP能否勝任?這取決于TCP的幾個特性。
首先TCP有慢啟動和滑動窗口的特性,TCP通過這種方式控制PU包,避免網絡阻塞。
TCP連接之后走一個慢啟動流程,這個流程從初始窗大小做2個N次方的擴張,最后到一定的域值,比如域值是16包,從16包開始逐步往上遞增,最后到24個數據包,這樣達到窗口最大值。
一旦遇到丟包的情況,當然兩種情況。一種是快速重傳,窗口簡單了,相當于是12個包的窗口。如果啟動一個RTO類似于狀態(tài)連接,窗口一下跌到初始的窗口大小。
如果啟動RTO重傳的話,對于后續(xù)包的阻塞蠻嚴重,一個包阻塞其他包的發(fā)送。
?
(▲ 上圖引用自《邁向高階:優(yōu)秀Android程序員必知必會的網絡基礎》)
有關TCP協(xié)議的基礎知識,可以讀讀以下資料:
《TCP/IP詳解?-?第17章·TCP:傳輸控制協(xié)議》
《TCP/IP詳解?-?第18章·TCP連接的建立與終止》
《TCP/IP詳解?-?第21章·TCP的超時與重傳》
《通俗易懂-深入理解TCP協(xié)議(上):理論基礎》
《通俗易懂-深入理解TCP協(xié)議(下):RTT、滑動窗口、擁塞處理》
《網絡編程懶人入門(一):快速理解網絡通信協(xié)議(上篇)》
《網絡編程懶人入門(二):快速理解網絡通信協(xié)議(下篇)》
《網絡編程懶人入門(三):快速理解TCP協(xié)議一篇就夠》
《腦殘式網絡編程入門(一):跟著動畫來學TCP三次握手和四次揮手》
《網絡編程入門從未如此簡單(二):假如你來設計TCP協(xié)議,會怎么做?》
8、TCP還是UDP?
?
(▲ 上圖引用自《移動端IM/推送系統(tǒng)的協(xié)議選型:UDP還是TCP?》)
TCP實現(xiàn)長連接的四個問題:
1)移動端的消息量還是比較稀疏,用戶每次拿到手機之后,發(fā)的消息總數比較少,每條消息的間隔比較長。這種情況下TCP的間連和保持長鏈接的優(yōu)勢比較明顯一些;
2)弱網條件下丟包率比較高,丟包后Block后續(xù)數據發(fā)送容易阻塞;
3)TCP連接超時時間過長,默認1秒鐘,這個由于TCP誕生的年代比較早,那會兒網絡狀態(tài)沒有現(xiàn)在好,當時定是1s的超時,現(xiàn)在可以設的更短一點;
4)在沒有快速重傳的情況下,RTO重傳等待時間較長,默認15分鐘,每次是N次方的遞減。
為何最終還是選擇TCP呢?因為我們覺得UDP更嚴重一點。
首先UDP沒有滑動窗口,無流量控制,也沒有慢啟動的過程,很容易導致丟包,也很容易導致在網絡中間狀態(tài)下丟包和超時。
UDP一旦丟包之后沒有重傳機制的,所以我們需要在應用層去實現(xiàn)一個重傳機制,這個開發(fā)量不是那么大,但是我覺得因為比較偏底層,容易出故障,所以最終選擇了TCP。
TCP還是UDP?這一直是個比較有爭議的話題:
《網絡編程懶人入門(四):快速理解TCP和UDP的差異》
《網絡編程懶人入門(五):快速理解為什么說UDP有時比TCP更有優(yōu)勢》
《5G時代已經到來,TCP/IP老矣,尚能飯否?》
《Android程序員必知必會的網絡通信傳輸層協(xié)議——UDP和TCP》
《不為人知的網絡編程(六):深入地理解UDP協(xié)議并用好它》
《不為人知的網絡編程(七):如何讓不可靠的UDP變的可靠?》
如果你對UDP協(xié)議還不了解,可以讀讀這篇:《TCP/IP詳解?-?第11章·UDP:用戶數據報協(xié)議》。
9、選擇TCP的更多理由
我們羅列一下,主要有這3點:
1)目前在移動端、安卓、IOS來說,初始窗口大小比較大默認是10,綜合TCP慢啟動的劣勢來看;
2)在普通的文本傳輸情況下,對于丟包的嚴重不是很敏感(并不是說傳多媒體的數據流,只是傳一些文本數據,這一塊對于丟包的副作用TCP不是特別嚴重);
3)我們覺得TCP在應用層用的比較多。
關于第“3)”點,這里有以下三個考量點。
第一個考量點:
基本現(xiàn)在應用程序走HTP協(xié)議或者是push方式基本都是TCP,我們覺得TCP一般不會出大的問題。
一旦拋棄TCP用UDP或者是QUIC協(xié)議的話,保不齊會出現(xiàn)比較大的問題,短時間解決不了,所以最終用了TCP。
第二個考量點:
我們的服務在基礎層上用哪種方式做LB,當時有兩種選擇,一種是傳統(tǒng)的LVS,另一種是HttpDNS(關于HttpDNS請見《全面了解移動端DNS域名劫持等雜癥:原理、根源、HttpDNS解決方案等》)。
最后我們選擇了HttpDNS,首先我們還是需要跨機房的LB支持,這一點HttpDNS完全勝出。其次,如果需要跨網端的話,LVS做不到,需要其他的部署方式。再者,在擴容方面,LVS算是略勝一籌。最后,對于一般的LB算法,LVS支持并不好,需要根據用戶ID的LB算法,另外需要一致性哈希的LB算法,還需要根據地理位置的定位信息,在這些方面HttpDNS都能夠完美的勝出,但是LVS都做不到。
第三個考量點:
我們在做TCP的飽和機制時通過什么樣的方式?Ping包的方式,間隔時間怎么確定,Ping包的時間細節(jié)怎么樣確定?
當時比較糾結是客戶端主動發(fā)ping還是服務端主動發(fā)Ping?
對于客戶端?;畹臋C制支持更好一些,因為客戶端可能會被喚醒,但是客戶端進入后臺之后可能發(fā)不了包。
其次:App前后臺對于不同的Ping包間隔來?;睿驗樵诤笈_本身處于一種弱在線的狀態(tài),并不需要去頻繁的發(fā)Ping包確定在線狀態(tài)。
所以:在后臺的Ping包的時間間隔可以長一些,前端可以短一些。
再者:需要Ping指數增長的間隔支持,在故障的時候還是比較救命的。
比如說:服務端一旦故障之后,客戶端如果拼命Ping的話,可能把服務端徹底搞癱瘓了。如果有一個指數級增長的Ping包間隔,基本服務端還能緩一緩,這個在故障時比較重要。
最后:Ping包重試是否需要Backoff,Ping包重新發(fā)Ping,如果沒有收到Bang包的話,需要等到Backoff發(fā)Ping。
10、動態(tài)Ping包時間間隔算法
PS:在IM里這其實有個更專業(yè)的叫法——“智能心跳算法”。
我們還設計了一個動態(tài)的Ping包時間間隔算法。
因為國內的網絡運營商對于NIT設備有一個保活機制,目前基本在5分鐘以上,5分鐘如果不發(fā)包的話,會把你的緩存給刪掉?;旧细鬟\營商都在5分鐘以上,只不過移動4G阻礙了?;究梢栽?到10分鐘之內發(fā)一個Ping包就行,可以維持網絡運營商設備里的緩存,一直保持著,這樣就沒有問題,使長連接一直?;钪?/p>
增加Ping包間隔可以減少網絡流量,能夠進一步降低客戶端的耗電,這一塊的受益還是比較大的。
在低端安卓設備的情況下,有一些DHCP租期的問題。這個問題集中在安卓端的低版本上,安卓不會去續(xù)租過期的IP。
解決問題也比較簡單,在DHCP租期到一半的時候,去及時向DHCP服務器續(xù)租一下就能解決了。
限于篇幅,我就不在這里展開了,有興趣可以讀這些資料:
《為何基于TCP協(xié)議的移動端IM仍然需要心跳?;顧C制?》
《一文讀懂即時通訊應用中的網絡心跳包機制:作用、原理、實現(xiàn)思路等》
《微信團隊原創(chuàng)分享:Android版微信后臺保活實戰(zhàn)分享(網絡?;钇?》
《移動端IM實踐:實現(xiàn)Android版微信的智能心跳機制》
《移動端IM實踐:WhatsApp、Line、微信的心跳策略分析》
《一種Android端IM智能心跳算法的設計與實現(xiàn)探討(含樣例代碼)》
《手把手教你用Netty實現(xiàn)網絡通信程序的心跳機制、斷線重連機制》
11、服務架構
11.1 基本介紹
服務架構比較簡單,大概是四個模塊:
1)首先是HttpDNS;
2)另一個是Connector接入層,接入層提供IP,
3)然后是Router,類似于代理轉發(fā)消息,根據IP選擇接入層的服務器,最后推到用戶;
4)最后還有認證的模塊Account,我們目前只是探探App,這個在用戶中心實現(xiàn)。
11.2 部署
部署上相當于三個模塊:
1)一個是Dispatcher;
2)一個是Redis;
3)一個是Cluser。
如下圖所示:客戶端在連接的時候:
1)需要拿到一個協(xié)議;
2)第二步通過HttpDNS拿到ConnectorIP;
3)通過IP連長連接,下一步發(fā)送Auth消息認證;
4)連接成功,后面發(fā)送Ping包?;?;
5)之后斷開連接。
11.3 消息轉發(fā)流程
消息轉發(fā)的流程分為兩個部分。
首先是消息上行:服務端發(fā)起一個消息包,通過Connector接入服務,客戶端通過Connector發(fā)送消息,再通過Connector把消息發(fā)到微服務上,如果不需要微服務的話直接去轉發(fā)到Vetor就行的,這種情況下Connector更像一個Gateway。
對于下行:業(yè)務方都需要請求Router,找到具體的Connector,根據Connector部署消息。
各個公司都是微服務的架構,長連接跟微服務的交互基本兩塊。一塊是消息上行時,更像是Gateway,下行通過Router接入,通過Connector發(fā)送消息。
11.4 一些實現(xiàn)細節(jié)
下面是一些是細節(jié),我們用了GO語言1.13.4,內部消息傳輸上是gRPC,傳輸協(xié)議是Http2,我們在內部通過ETCD做LB的方式,提供服務注冊和發(fā)現(xiàn)的服務。
如下圖所示:Connector就是狀態(tài),它從用戶ID到連接的一個狀態(tài)信息。
我們看下圖的右邊:它其實是存在一個比較大的MAP,為了防止MAP的鎖競爭過于嚴重,把MAP拆到2到56個子MAP,通過這種方式去實現(xiàn)高讀寫的MAP。對于每一個MAP從一個ID到連接狀態(tài)的映射關系,每一個連接是一個Go Ping,實現(xiàn)細節(jié)讀寫是4KB,這個沒改過。
我們看一下Router:它是一個無狀態(tài)的CommonGRPC服務,它比較容易擴容,現(xiàn)在狀態(tài)信息都存在Redis里面,Redis大概一組一層,目前峰值是3000。
我們有兩個狀態(tài):一個是Connector,一個是Router。
首先以Connector狀態(tài)為主,Router是狀態(tài)一致的保證。
這個里面分為兩種情況:如果連接在同一個Connector上的話,Connector需要保證向Router復制的順序是正確的,如果順序不一致,會導致Router和Connector狀態(tài)不一致。通過統(tǒng)一Connector的窗口實現(xiàn)消息一致性,如果跨Connector的話,通過在Redis Lua腳本實現(xiàn)Compare And Update方式,去保證只有自己Connector寫的狀態(tài)才能被自己更新,如果是別的Connector的話,更新不了其他人的信心。我們保證跨Connector和同一Connector都能夠去按照順序通過一致的方式更新Router里面連接的狀態(tài)。
Dispatche比較簡單:是一個純粹的Common Http API服務,它提供Http API,目前延時比較低大概20微秒,4個CPU就可以支撐10萬個并發(fā)。
目前通過無單點的結構實現(xiàn)一個高可用:首先是Http DNS和Router,這兩個是無障礙的服務,只需要通過LB保證。對于Connector來說,通過Http DNS的客戶端主動漂移實現(xiàn)連接層的Ordfrev,通過這種方式保證一旦一個Connector出問題了,客戶端可以立馬漂到下一個Connector,去實現(xiàn)自動的工作轉移,目前是沒有單點的。? ?? ???
12、性能優(yōu)化
12.1 基本情況
后續(xù)有優(yōu)化主要有以下幾個方面:
1)網絡優(yōu)化:這一塊拉著客戶端一起做,首先客戶端需要重傳包的時候發(fā)三個嗅探包,通過這種方式做一個快速重傳的機制,通過這種機制提高快速重傳的比例;
2)心跳優(yōu)化:通過動態(tài)的Ping包間隔時間,減少Ping包的數量,這個還在開發(fā)中;
3)防止劫持:是通過客戶端使用IP直連方式,回避域名劫持的操作;
4)DNS優(yōu)化:是通過HttpDNS每次返回多個IP的方式,來請求客戶端的HttpDNS。
12.2 網絡優(yōu)化
對于接入層來說,其實Connector的連接數比較多,并且Connector的負載也是比較高。
我們對于Connector做了比較大的優(yōu)化,首先看Connector最早的GC時間到了4、5毫秒,慘不忍睹的。
我們看一下下面這張圖(圖上)是優(yōu)化后的結果,大概平均100微秒,這算是比較好。第二張圖(圖下)是第二次優(yōu)化的結果,大概是29微秒,第三張圖大概是20幾微秒。
12.3 消息延遲
看一下消息延遲,探探對im消息的延遲要求比較高,特別注重用戶的體驗。
這一塊剛開始大概到200ms,如果對于一個操作的話,200ms還是比較嚴重的。
第一次優(yōu)化之后(下圖-上)的狀態(tài)大概1點幾毫秒,第二次優(yōu)化之后(下圖-下)現(xiàn)在降到最低點差不多100微秒,跟一般的Net操作時間維度上比較接近。
12.4 Connector優(yōu)化過程
優(yōu)化過程是這樣的:
1)首先需要關鍵路徑上的Info日志,通過采樣實現(xiàn)Access Log,info日志是接入層比較重的操作;
2)第二通過Sync.Poll緩存對象;
3)第三通過Escape Analysis對象盡可能在線上分配。
后面還實現(xiàn)了Connector的無損發(fā)版:這一塊比較有價值。長連接剛上線發(fā)版比較多,每次發(fā)版對于用戶來說都有感,通過這種方式讓用戶盡量無感。
實現(xiàn)了Connector的Graceful Shutdown的方式,通過這種方式優(yōu)化連接。
首先:在HttpDNS上下線該機器,下線之后緩慢斷開用戶連接,直到連接數小于一定閾值。后面是重啟服務,發(fā)版二進制。
最后:是HttpDNS上線該機器,通過這種方式實現(xiàn)用戶發(fā)版,時間比較長,當時測了挺長時間,去衡量每秒鐘斷開多少個連接,最后閾值是多少。
后面是一些數據:剛才GC也是一部分,目前連接數都屬于比較關鍵的數據。首先看連接數單機連接數比較少,不敢放太開,最多是15萬的單機連接數,大約100微秒。
Goroutine數量跟連接數一樣,差不多15萬個:
看一下內存使用狀態(tài),下圖(上)是GO的內存總量,大概是2:3,剩下五分之一是屬于未占用,內存總量是7.3個G。
下圖是GC狀態(tài),GC比較健康,紅線是GC每次活躍內存數,紅線遠遠高于綠線。
看到GC目前的狀況大概是20幾微秒,感覺目前跟GO的官方時間比較能對得上,我們感覺GC目前都已經優(yōu)化到位了。
12.5 后續(xù)要做的優(yōu)化
最后是規(guī)劃后續(xù)還要做優(yōu)化。
首先:對系統(tǒng)上還是需要更多優(yōu)化Connector層,更多去減少內存的分配,盡量把內存分配到堆上而不是站上,通過這種方式減少GC壓力,我們看到GO是非Generational Collection GE,堆的內存越多的話,掃的內存也會越多,這樣它不是一個線性的增長。
第二:在內部更多去用Sync Pool做短暫的內存分配,比如說Context或者是臨時的Dbyle。
協(xié)議也要做優(yōu)化:目前用的是WebSocket協(xié)議,后面會加一些功能標志,把一些重要信息傳給服務端。比如說一些重傳標志,如果客戶端加入重傳標志的話,我們可以先校驗這個包是不是重傳包,如果是重傳包的話會去判斷這個包是不是重復,是不是之前發(fā)過,如果發(fā)過的話就不需要去解包,這樣可以少做很多的服務端操作。
另外:可以去把Websocket目前的Mask機制去掉,因為Mask機制防止Web端的改包操作,但是基本是客戶端的傳包,所以并不需要Mask機制。
業(yè)務上:目前規(guī)劃后面需要做比較多的事情。我們覺得長連接因為是一個接入層,是一個非常好的地方去統(tǒng)計一些客戶端的分布。比如說客戶端的安卓、IOS的分布狀況。
進一步:可以做用戶畫像的統(tǒng)計,男的女的,年齡是多少,地理位置是多少。大概是這些,謝謝!
13、熱門問題回復
* 提問:剛才說連接層對話重啟,間接的過程中那些斷掉的用戶就飄到其他的,是這樣做的嗎?
張凱宏:目前是這樣的,客戶端做自動飄移。
* 提問:現(xiàn)在是1千萬日活,如果服務端往客戶端一下推100萬,這種場景怎么做的?
張凱宏:目前我們沒有那么大的消息推送量,有時候會發(fā)一些業(yè)務相關的推送,目前做了一個限流,通過客戶端限流實現(xiàn)的,大概三四千。
* 提問:如果做到后端,意味著會存在安全隱患,攻擊者會不停的建立連接,導致很難去做防御,會有這個問題嗎?因為惡意的攻擊,如果攻擊的話建立連接就可以了,不需要認證的機制。
張凱宏:明白你的意思,這一塊不只是長連接,短連接也有這個問題??蛻舳艘恢痹趥卧煸L問結果,流量還是比較大的,這一塊靠防火墻和IP層防火墻實現(xiàn)。
* 提問:長連接服務器是掛在最外方,中間有沒有一層?
張凱宏:目前接著如下層直接暴露在外網層,前面過一層IP的防DNSFre的防火墻。除此之外沒有別的網絡設備了。
* 提問:基于什么樣的考慮中間沒有加一層,因為前面還加了一層的情況。
張凱宏:目前沒有這個計劃,后面會在Websofte接入層前面加個LS層可以方便擴容,這個收益不是特別大,所以現(xiàn)在沒有去計劃。
* 提問:剛剛說的斷開重傳的三次嗅探那個是什么意思?
張凱宏:我們想更多的去觸發(fā)快速重傳,這樣對于TCP的重傳間隔更短一些,服務端根據三個循環(huán)包判斷是否快速重傳,我們會發(fā)三個循環(huán)包避免一個RTO重傳的開啟。
* 提問:探探最開始安卓服務器是使用第三方的嗎?
張凱宏:對的,剛開始是極光推送的。
* 提問:從第三方的安卓服務器到自研。
張凱宏:如果極光有一些故障的話,對我們影響還是蠻大。之前極光的故障頻率挺高,我們想是不是自己能把服務做起來。第二點,極光本身能提供一個用戶是否在線的判斷,但是它那個判斷要走通道,延時比較高,本身判斷是連接把延時降低一些。
* 提問:比如說一個新用戶上線連接過來,有一些用戶發(fā)給他消息,他是怎么把一線消息拿到的?
張凱宏:我們通過業(yè)務端保證的,未發(fā)出來的消息會存一個ID號,當用戶重新連的時候,業(yè)務端再拉一下。
14、參考資料
[1]?移動端IM/推送系統(tǒng)的協(xié)議選型:UDP還是TCP?
[2]?5G時代已經到來,TCP/IP老矣,尚能飯否?
[3]?為何基于TCP協(xié)議的移動端IM仍然需要心跳?;顧C制?
[4]?一文讀懂即時通訊應用中的網絡心跳包機制:作用、原理、實現(xiàn)思路等
[5]?微信團隊原創(chuàng)分享:Android版微信后臺?;顚崙?zhàn)分享(網絡?;钇?
[6]?移動端IM實踐:實現(xiàn)Android版微信的智能心跳機制
[7]?邁向高階:優(yōu)秀Android程序員必知必會的網絡基礎
[8]?全面了解移動端DNS域名劫持等雜癥:原理、根源、HttpDNS解決方案等
[9]?技術掃盲:新一代基于UDP的低延時網絡傳輸層協(xié)議——QUIC詳解
[10]?新手入門一篇就夠:從零開發(fā)移動端IM
[11]?長連接網關技術專題(二):知乎千萬級并發(fā)的高性能長連接網關技術實踐
[12]?長連接網關技術專題(三):手淘億級移動端接入層網關的技術演進之路
[13]?長連接網關技術專題(五):喜馬拉雅自研億級API網關技術實踐
[14]?一套億級用戶的IM架構技術干貨(上篇):整體架構、服務拆分等
[15]?一套億級用戶的IM架構技術干貨(下篇):可靠性、有序性、弱網優(yōu)化等
[16]?從新手到專家:如何設計一套億級消息量的分布式IM系統(tǒng)
本文已同步發(fā)布于“即時通訊技術圈”公眾號。
同步發(fā)布鏈接是:http://www.52im.net/thread-3780-1-1.html