高并发IM系统架构优化实践
互聯網+時代,消息量級的大幅上升,消息形式的多元化,給即時通訊云服務平臺帶來了非常大的挑戰。高并發的IM系統背后究竟有著什么樣的架構和特性?
以上內容由網易云信首席架構師內部分享材料整理而成相關閱讀推薦:
推送保障及網絡優化詳解:如何實現不影響用戶體驗的后臺保活
推送保障及網絡優化詳解:如何做長連接加推送組合方案
本文要點:
l? 網易云信整體架構解析
l? 云信中的客戶端連接和接入點管理
l? 服務化和高可用
?
網易IM云分層架構圖解析
1,底層客戶端?SDK,覆蓋了安卓,iOS,windows PC 桌面端,web 網頁端和嵌入式設備等多個平臺。在 SDK 層使用的網絡協議有4層的 TCP 協議和基于7層的 Socket.IO 協議,后者專門用于 Web SDK 中提供長連接能力;除了集成到應用 App 中的 SDK 之外,還提供了供第三方服務器調用的 API 接口,基于 Http 協議;最后的 A/V SDK 是基于 UDP 協議的實時音視頻SDK ,用于實現基于網絡的語音和視頻通話。
(網易IM云分層架構圖)
?
2,網關層:提供客戶端直接接入并維護與服務器之間的長連接;其中 WebSDK 直連的是 Weblink 服務,這是一個基于Socket.IO 協議實現的長連接服務,而供 AOS/IOS/PC 等客戶端 SDK 直連的是基于 TCP 協議的Link服務;在 Link 和 WebLink服務中承擔的一個非常重要的功能就是所有客戶端長連接的管理,后面基于 HTTP 協議上的網關有 API 服務,和 LBS 服務等,其中 LBS 服務用于幫助客戶端 SDK 選取最合適自己的網關接入點,優化網絡效率;而 API 服務則直接提供來自第三方服務器的業務請求;
?3,HA 層:在網關接入層之上是HA層,網關接入層可提供給客戶端直連,在 link 層和 Service 層之間有一個 HA 層用來解耦并提供高可用和易擴展等特性;在 HA 的具體實現方式上,對 Link 和 WebLink 這兩個維持客戶端長連接的服務,云信提供了協議路由的服務,代為分發業務請求,路由層會按照預定義的規則將來自客戶端的請求轉發到相應的業務節點上,當業務集群擴容之后路由服務馬上能發現新的可用節點,并將請求轉發過去,當發現業務節點出現異常時也會被路由層標記并隔離下線以備替換。
?4,業務節點集群:在 HA 層上就是具體的業務節點集群,我們稱為 App 服務,該服務處理具體的客戶端請求,后端直連 DB、cache 等各種基礎服務,這個集群中的節點的特點是輕量,并且每個節點都是無狀態的,云信在實際部署這個集群時會跨網絡環境部署,比如在同城雙機房中分別部署一套業務服務節點,前端通過路由層來分發業務請求,平時正常時業務互為熱備,平均分擔線上的業務流量;當單一網絡環境或者基礎設施出現故障時馬上會被路由服務檢測到,并將該環境下的計算節點標記下線,將線上的流量請求全部轉發到正常工作的集群中;從而提高了服務的整體可用性;配合監控平臺等運維工具,業務節點的實時處理能力和容量使用情況都會被動態監測起來,當處理能力達到預設的水位線時會立即出發報警,運維人員可以非常方便快捷得通過自動部署平臺對業務節點集群進行擴容。
?5,業務層:其中包含了一些關鍵功能:核心的單聊消息、群聊消息和聊天室,通知等;以及用戶信息托管,特殊關系管理等;還有面向 API 提供的如短信業務,回撥電話和專線會議等;還有實時音視頻和直播功能等相關能力。
最右邊列出的是從服務層上單獨列出來的更重要的功能,包括與開發者應用的第三方數據同步,個性化的內容審核支持,超大群服務,登陸登出事件日志,漫游消息和云端消息歷史功能,推送服務等等。
?
網易IM云部署拓撲
通過以下這張簡化后的部署拓撲圖可以對云信整體技術體系的有初步了解。最右邊是客戶端,客戶端通過 LBS 服務獲取到網關接入點列表,再與 Link 和 WebLink 這類長連接服務器建立起長連接,并進行 RPC 操作,所有來自客戶端的請求都會通過路由層轉發到后端的 APP 層,APP 層實時處理并下發同步請求的處理結果,并把一些異步任務通過隊列服務送到異步任務中,這些異步服務如大群消息的發送,推送服務,云端歷史消息的存儲和第三方的數據抄送同步服務等;在最下面的 API 接口上也是類似,API 直接提供給第三方的服務器調用請求,API 后端是各種獨立的業務,如回撥電話,短信等;同樣的所有的 API 后端業務請求也會產生相應的日志;和 APP 上的日志樣,這些日志都會被通過日志采集平臺收集到大數據平臺中,一方面這類數據會存儲到HDFS 上用于作為數據統計分析的數據源;另一方面會被導入到 Hbase 等數據倉庫中,用于提供日志檢索和二次分析。
(網易IM云部署拓撲示意)
?
?高并發IM系統連接層的優化實踐
?即時通訊功能中最重要的連接管理服務怎么做?消息快速到達的前提是客戶端和服務器之間保持了穩定的連接;可以理解為奠定云信服務穩定性的基石。網關接入層需要解決的最重要的問題是什么?核心依然是穩定,安全和快速。
如何保證穩定?網易云信 SDK 采用長連接機制來實現,并且由心跳的方式來檢測斷線和自動做重連,同時云信的 SDK 對移動網絡等弱網環境非常多的優化工作,對移動端/PC端使用 TCP 來連接客戶端與服務器,對與 Web 端使用 socketIO 協議,實現長連接的同時解決瀏覽器的兼容性問題;
?
如何實現安全?,云信要求所有在公網傳輸的數據都必須被加密;在 SDK 與服務器的連接建立過程中有一個復雜的秘鑰協商過程,首先客戶端需要生成一個一次性使用的加密秘鑰,并使用非對稱加密方式將這個秘鑰加密之后傳給服務器,加密數據會被服務器解密,之后該加密秘鑰被保留在該長連接的會話信息中,數據來往均使用該秘鑰加密,這是一個流式加密,可以有效防止中間人攻擊和數據包回放等攻擊手段。
?
如何保證快速?首先是在網關接入點的選擇上,借助 LBS 服務可以幫助客戶端尋找到最適合自己的網關接入點,比如從 ip 等信息判斷到的物理距離最近節點,其次在連接建立之后,長連接的機制可以極大提升消息上下行的速度,并且在數據傳輸過程中,云信會對數據包壓縮傳輸,降低網絡開銷來升消息收發的速度;對頻繁的前后臺切換和重登陸這種移動客戶端場景,SDK 提供自動登錄和重連等機制,即在 UI 界面起來的同時已經提前把消息通道建立;在接入網關的選擇策略中,通過并行來提升連接建立的速度(展示圖);
?
客戶端與服務器建立長連接的過程展現
?
SDK 接入的第一步是先請求 LBS 服務,獲取可以進入的接入網關地址列表,LBS 服務會根據多種策略條件來給客戶端分配地址,常見的條件如下:
1:appkey, 通過 appkey 可以將一個特定的應用請求全部指向到一組特定的接入點,可用于專屬服務器方案;
2:客戶端 ip,用于根據客戶端所處的地理位置,為其就近分配接入網關,常見于海外節點的配置;
3. SDK 版本號,將特定版本范圍的客戶端指向到特定網關,常用于新老版本升級的兼容方案,目前無實際使用案例;
4. 特定環境標識,如智能客服環境等,用于將特定類型的 app 指向到特定網關,用于較大粒度環境隔離需求;
在從 LBS 服務請求到接入網關地址之后,客戶端會按列表中的地址依次嘗試建立連接;如果嚴格按照這樣的順序,那客戶端建立連接的過程就會偏慢,為了加速接入過程,實際上在操作時,SDK 都會使用本地緩存的最后一次 LBS 請求返回的地址列表來建立連接,同從 LBS 上拿一次新的地址列表緩存在本地,以備下次使用;當列表中的所有地址在嘗試過一遍均失效,則會使用默認的 link 地址來建立連接;默認地址也失敗是會出現415或者408這種網絡錯誤碼;
?
在獲取到目標地址之后就會嘗試建立 TCP 長連接,連接建立之后就會與服務器協商加密秘鑰,并發出第一個鑒權包,鑒權完成之后這個長連接就是一個安全有效的連接,客戶端可以發起后續的 RPC 請求;服務器也可以往這個連接上下發消息通知;如果秘鑰協商失敗或者鑒權失敗,這個連接就會被認為是一個非法的連接請求,服務器會強制斷開;
?
最后聊一下加速節點的問題,為了實現連接的快速,在網關接入點的分配時會優先距離該客戶端最近的節點;這里將的加速節點就是為了更靠近用戶提供的一種特殊節點。
加速節點的原理背景是運營商提供給個人用戶的線路,不管是移動網絡還是有線網絡,其質量和 IDC 中心之間的網絡總是有差異的;如果將整個用戶鏈路中的關鍵路徑替換成 IDC 之間的網絡線路,那么對提升連接的穩定性和速度是有幫助的。
?
假設一個處于美國的客戶通過手機網絡訪問位于杭州的一個網關接入點,由于客戶端所在的網絡是一個移動網絡,直連到杭州服務器需要經過的鏈路非常長而且可能跳轉的中間節點不可預期,在中國來說,還要跨越防火墻;所以直連的情況大部分可能就是無法連接,或者連接之后頻繁斷線。
我們提供了多層的加速節點:加入了加速節點之后,用戶的整體鏈路中原來不可預期的那段鏈路都換成了質量較好的線路,用戶直連到本地的加速節點的網絡往往就會好很多。
?
下面說說不同的投遞模式對消息送達效率的影響:
問題一:怎么讓消息投遞并發能力倍增?在這張圖中,上半部分表示的是一個點對點型的 Link 服務器,當發送者A發送一條消息之后,通過 Link 這條消息提交到 APP 中處理,APP 中查詢到該消息接收者B所在的 Link 服務器是 Link y,于是向 Link y 服務器下發一條下行通知包,Link y上再找到用戶B對應的長連接并將通知下發到客戶端;這種模式下,所有的接入點 Link 對于所有的用戶來說都是對等的,他可以接入到任何一個服務器中,任何消息的發送都必須在業務層查詢到目標接收者所在的 Link 服務器,并往相應的 Link 服務器下發通知包,如果是一次群發行為,那就需要在業務 APP 上把所有群內的成員所在的 Link 列表都查詢一遍;這是一個比較耗時的操作;并且是隨著消息接收成員的數量不斷上升開銷不斷增大;所以如果是需要往聊天室內發送消息,由于聊天室內的成員數量非常龐大,這種模式很快就會遇到性能瓶頸,消息投遞的延時會非常嚴重;
?
對于廣播型的 Link 服務器,云信在分配接入點時首先遵循一個原則,那就是同個聊天室內的成員在分配聊天室時,盡量分配在同一組接入點上;在 Link 上維護了每個房間內所有的成員的長連接集合;而在 App 上維護的不再是特定用戶和 Link 之前的映射關系,而是維護了特定房間分配的 Link 的集合;于是在任何一個成員發出一條聊天室廣播消息之后,消息通過 link 上行到App,App 只要找到該聊天室已經分配的 Link 地址列表,往每個 Link 上下發一個廣播消息,Link 在收到下行的廣播消息之后再在本地做廣播分發;這個效率比點播的模式高出了不止一個數量級;
?
問題二:怎么解決單節點的性能瓶頸?
?
在講完了點對點型和廣播型這兩種 Link 的區別之后;云信再回頭來看看另外一類基于 socket.io 實現的 weblink 的代理方案在云信中的演變優化過程;
在這之前需要再強調下 WebLink 中兩個關鍵點,首先 WebLink 是基于 Socket.io 協議的,為了保證數據通道的可靠,云信需要使用 Https 來對通道加密,其次由于是 Https 的請求所以必須提供獨立的域名。
圖一中顯示的是最早的方案,后端 Weblink 提供連接,并實現 SSL 加密,多個節點前面通過 LVS 做代理,域名綁定在 LVS 代理之上,LVS代理之上再做 Keepalived 方案來保證HA;這種方案對外暴露的域名只有一個,而內部實際有很多的節點,擴容對外也是透明的;Web客戶端在連接時只需要直連這個唯一域名就可以,對于單一產品來說這種方式最簡便快捷,客戶端可以繞過地址分配的過程;缺點也集中在單一出口,如果這個單一出口受到DDOS攻擊,只能通過域名換綁來規避,而域名換綁需要一定的生效時間,帶來和一些運維上的代價,其次對于云信這種服務來說,單一出口就喪失了靈活性;所有客戶直連到同一個入口,也無法實現專屬服務和業務隔離,無法實現加速節點方案;
于是便有了第二種方案,這種方案借鑒了Link業務中的LBS分配的方式,還是在Weblink節點上實現SSL加密,并為每個Weblink節點分配獨立域名,客戶端在接入前先通過LBS服務來分配到合適的接入點;這種方案好處就是提供了更大的靈活性,隨時可以給集群擴容,也可以動態調整特定應用的接入點地址,也提供做加速節點的可能性;但是這種方案的問題是每個節點都是單點,而且節點內還是需要做SSL編碼,由于java的SSL對cpu資源開銷比較大,在突發用戶流量是會影響單個節點的服務能力;
于是又有了第三種方案,這種方案前端使用Nginx做七層代理,并在Nginx配置SSL和域名綁定,后端可以同時使用一組Weblink;由于使用了Nginx,在端口的分配邏輯上也更加科學,提高了運維的便捷性;最后云信就得到了目前在使用的一個組合方案,前端還是通過LBS服務來為SDK分配接入點,以此提供靈活性;后端使用多個Nginx集群做代理集群,每個集群分組的性能都得到了提高。
?
?
即時通訊平臺服務化和高可用實踐
?
前面重點介紹了云信在客戶端接入層的實現和接入點的管理上使用的一些方法,通過這些技術手段為IM服務建立了一條穩定可靠的消息通道,現在來聊聊在業務層做的服務化和高可用上面的工作。
網關接入層負責客戶端長連接的維護和管理,所有的接入節點甚至可以是無狀態的對等節點,只負責客戶端與服務器之間請求的傳遞的轉發,并優化轉發效率;而真正的業務處理邏輯還是需要有業務層來實現。
?
業務層需要處理大量請求并負責和DB,緩存,隊列,第三方接口等組件的交互,其穩定性,可用性和擴展能力直接影響了整個云服務的質量;為了使業務層具有更好的彈性,云信在網關接入層和業務層之間引入了一個路由層來解耦;業務節點在上線之后會將自己注冊到服務中心,路由節點會轉接網關層的請求包,并從服務節點中挑選匹配的節點分發請求;這種三層架構使系統整體具有更好的彈性。
?
?
為了提高業務的可用性,云信會將業務節點分布到分屬于不同網絡的環境中,正常情況下可以同時提供服務,一旦其中一個環境的網絡或者基礎設施出現故障,就可以快速得通過路由層來將故障集群下線。
靈活支持灰度升級模式,云信可以將其中部分業務節點升級,然后通過路由層的配置將指定的用戶流量導入到新升級的節點中;
專屬服務的靈活支持,對于一些對資源獨占需求比較強烈的客戶,云信可以通過路由層將該客戶應用下的所有流量導入到獨立的集群中。
總結
以上是生活随笔為你收集整理的高并发IM系统架构优化实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 世界杯直播“三分天下”,视频平台如何实现
- 下一篇: Android 即时通讯开发小结(二)