前言
聊天室是一類非常重要的 IM 系統,不同於單聊和群聊,聊天室是一種大規模的實時消息分發系統。
聊天室有多種技術實現方案,業界也有一些開源的實現,每種實現都有自己的特點和應用場景。網易雲信作為 PaaS 平台,其聊天室的系統架構和方案有幾個突出的特點:
- 水平擴展能力:主要體現在兩方面,一個是聊天室數量,一個是單個聊天室的人數。
- 功能豐富:作為一個平台,聊天室提供底層通信能力,提供了豐富的功能集,來適配各種各樣的業務場景,使用方可以根據自己的業務要求按需使用。
- 支持全球化:雲信目前提供了覆蓋全球的通信網絡,通過接入雲信自研的 WE-CAN 大網,全球范圍內延遲不超過 250ms。
本文我們來詳細介紹一下網易雲信大規模聊天室系統的具體架構以及實踐應用案例。
網易雲信聊天室系統架構
首先,我們先來看一下網易雲信當前聊天室的詳細技術架構,以及我們在架構升級優化過程中做的一些事情。
整體架構圖
如下圖,是網易雲信聊天室的技術架構:
主要包括以下部分:
- 接入層的 ChatLink
- 網絡傳輸層的 WE-CAN、WE-CAN bridge
- 調度層的 Dispatcher
- 服務層的 Callback、Queue、Presence、Tag、History 等
- CDN 分發層的 CDN Manager、CDN Pusher、CDN Source
下面,我們針對每一層展開詳細分析。
接入層
接入層根據客戶端的類型不同會有不同的實現,例如常見客戶端(iOS、Andriod、Windows、Mac 等)基於私有二進制協議,Web 端基於 Websocket 協議實現。接入層作為距離客戶端的最后一公里,其接入速度、質量以及數據安全都是至關重要的:
接入速度和質量
目前我們搭建了覆蓋全國各省份以及全世界各大洲的邊緣節點,縮短最后一公里,減少不確定性,提升服務的穩定性。
數據安全
基於對稱+非對稱加密,客戶端與服務器之前實現 0-RTT,完成秘鑰交換和登錄,同時也支持 RSA/AES/SM2/SM4 等各種加密算法。
接入層除了接受來自客戶端的請求,還負責進行消息的單播和廣播,因此接入層需要管理本節點的所有長連接,包括每個聊天室房間的連接以及每個連接的標簽屬性。此外接入層會上報自己的負載信息給后端服務,方便調度層進行合理的調度。
當流量洪峰來臨時,因為需要進行消息的廣播,接入層往往是壓力最大的,為了保證服務的穩定性,我們做了很多優化策略:
自適應的流控策略
- 單機流控:接入層服務會監控本機整體的網絡帶寬使用情況,並設置 2 個閾值 T1 和 T2,當帶寬使用率超過 T1 時,觸發流控,如果進一步超過了 T2,則不僅觸發流控還會不斷的調整流控的強度。最終的目標是使帶寬使用率穩定在 T1 和 T2 之間。
- 單連接流控:除此之外,接入層服務還會記錄每個長連接的消息分發速度,並進行細粒度的調整,避免單機粗粒度流控導致單個連接分發過少或者過多,做到消息分發的平滑,即減少了帶寬流量的波動尖刺,也改善了端側的體驗。
性能優化
ChatLink 高負載運行時,除了網絡帶寬,調用鏈路上的各個環節都可能成為性能的瓶頸。我們通過減少編解碼的次數(包括序列化、壓縮等)、多線程並發、減少內存拷貝、消息合並等多種方式,顯著地提升了服務性能。
網絡傳輸層
網易雲信聊天室系統最初的架構是將接入層和后端服務層部署在同一個機房的,大部分用戶都是直連 BGP 機房的 ChatLink,對於偏遠地區或者海外,則通過專線的方式部署代理節點完成加速。該方案存在明顯的缺點就是服務能力上限受制於單機房的容量,此外,專線也是一筆不小的開銷。
在我們接入 WE-CAN 大網后,接入層 ChatLink 可以做到客戶端就近接入,提高服務質量的同時降低了成本。此外,多機房的架構也使得我們的服務能力上升了一個台階。
為了適配 WE-CAN 大網,我們設計了 WE-CAN Bridge 層,作為大網接入協議和聊天室協議的橋接層,負責協議轉換、會話管理、轉發接收。通過這種分層架構,接入層和后端業務層可以少修改或者不修改,減少對已有系統的改造成本,也降低了架構升級帶來的風險。
調度層
調度層是客戶端接入聊天室系統的前提。客戶端登錄聊天室之前需要先獲取接入地址,分配服務我們稱之為 Dispatcher。
Dispatcher 是中心化的,會接受來自 WE-CAN 和 ChatLink 的心跳信息,根據心跳情況來選擇最佳接入點,調度系統設計主要考慮的幾個關鍵點是:
調度精度
調度系統會根據請求方的 IP 判斷地域和運營商信息,對比各個邊緣節點的所屬區域、運營商以及節點本身的負載(如 CPU、網絡帶寬等),此外還考慮邊緣節點到中心機房的鏈路情況(來自 WE-CAN),計算綜合打分,並把最優的若干節點作為調度結果。
調度性能
面對高並發場景,比如一個大型聊天室,活動初期往往伴隨着大量人員的同時進入,此時就需要調度系統做出快速的反應。為此,我們會將上述的調度規則以及原始數據進行本地緩存優化,此外,為了避免心跳信息滯后導致分配不合理引起節點過載,分配服務時還會動態調整負載因子,在保證調度性能的前提下,盡量做到分配結果的平滑。
服務層
服務層實現了各種業務功能,包括:在線狀態、房間管理、雲端歷史、第三回調、聊天室隊列、聊天室標簽等。其中最基礎的是在線狀態管理和房間管理:
- 在線狀態管理:管理某個賬號的登錄狀態,包括登錄了哪些聊天室、登錄在了哪些接入點等
- 房間管理:管理某個聊天室房間的狀態,包括房間分布在哪些接入點,房間里有哪些成員等
在線狀態管理和房間管理的難點在於如何有效管理海量用戶和房間。網易雲信 PaaS 平台的特性,使得我們可以根據不同的租戶來進行 Region 划分,從而做到水平擴展。此外,由於狀態數據有快速變化的特點(短 TTL),當某些核心用戶或者某個客戶報備了大型活動時,雲信可以在短時間內進行相關資源的快速拆分和隔離。
服務層除了要支持海量客戶接入、水平擴展外,還有一個很重要能力,就是需要提供各種各樣的擴展性功能來適配客戶各種應用場景。為此雲信提供了各種各樣豐富的功能,比如:
- 第三方回調:方便客戶干預 C 端用戶的登錄、發消息等核心環節,自定義實現各種業務邏輯。因為涉及到服務調用,而這個調用是跨機房甚至是跨地區的,為了避免第三方服務故障導致雲信服務異常,我們設計了隔離、熔斷等機制來減少對關鍵流程的影響;
- 聊天室隊列:可以方便用戶實現一些諸如麥序、搶麥等業務場景需求;
- 聊天室標簽:作為雲信業內首創的特色功能,支持消息的個性化分發。其實現原理是通過客戶端登錄時設置標簽組以及發消息時設置標簽表達式,來定義消息分發和接收的規則。標簽信息會同時保存在服務層以及接入層,通過將部分標簽計算下推到接入層,節省了中心服務的帶寬和計算資源。
CDN 分發層
當我們評價一個聊天室系統時,常用的一個詞是無上限。架構支持無上限不代表真的無上限。一個聊天室系統,在邏輯上,各個組成單元都是可以水平擴展的,但是每個服務所依賴的物理機、交換機、機房帶寬等都是有容量上限的。因此,能夠合理地調配多個地域的多個機房,甚至是外部的其他資源,才能真正體現出一個聊天室系統所能支撐的容量上限。
在網易雲信的聊天室系統中,用戶所有的接入點遍布各地機房,天然的將各地的資源進行了整合,所能支撐的容量上限自然高於單機房或者單地區多機房的部署模式。
進一步的,當面臨一個更大規模的聊天室,此時如果能利用一些外部的通用能力不失為一種合適的選擇。融合 CDN 彈幕方案就是這樣一種技術實現方案,它可以利用各大 CDN 廠商部署在各地的邊緣節點,利用靜態加速這樣的通用能力來支持超大規模的聊天室消息分發。
基於融合 CDN 彈幕分發方案,其核心點就是彈幕的分發和管理,這是一個可選的模塊,雲信內部對此進行了封裝,可以根據不同的業務特點來選擇是否開啟而不需要修改任何業務代碼。
在開啟融合 CDN 彈幕分發方案的情況下,所有的彈幕廣播會划分成 兩條鏈路:
- 重要的且需要實時送達的消息會走長連接到達客戶端
- 其他的海量消息則會進入 CDN Pusher,通過各種策略進行聚合后送達 CDN Source
客戶端 SDK 會采取一定的策略定時從 CDN 邊緣節點獲取彈幕消息。SDK 會聚合不同來源的消息,排序后回調給用戶,App 層無需關系消息來自哪里,只需根據自己的業務需求進行處理即可。
如上圖,展示了 CDN 彈幕分發鏈路的消息流轉過程:CDN Manager 負責管理不同 CDN 廠商的分配策略(登錄時會通過長連接下發,且能動態調整)。此外,還負責管理平台上各個聊天室融合 CDN 模式的開啟和關閉,以及對應的 CDN Pusher 資源的調配和回收。CDN Pusher 實際負責接收來自客戶端消息,並根據消息的類型、消息的優先級等,組裝成以一個一個的靜態資源,推給 CDN Source,等待 CDN 回源拉取。
落地實踐案例
下面,我們介紹應用了網易雲信聊天室系統的典型應用場景。
大規模場景應用案例
在2020年8月,網易雲音樂 TFBoys 的 7 周年線上演唱會就是一個聊天室大規模場景應用的典型案例。在這場活動創造了 78w+ 的在線付費演唱會的世界紀錄,其彈幕互動的實現方式采用了網易雲信基於融合 CDN 彈幕分發方案。事實上,在籌備環節,我們的聊天室系統達成了 20 分鍾完成從 0 到 1000w 在線,上行消息 tps 達到 100w 的性能指標。
如上圖,是支持本次活動彈幕分發的架構圖,普通彈幕和禮物消息分別通過客戶端 SDK 以及服務器 API 到達雲信服務器,並最終進入彈幕廣播服務,隨后分流到長連接和 CDN 上,再通過 pull / push 混合的方式送達客戶端。
特色功能 - 聊天室標簽應用案例
近年來,隨着互聯網的發展,在線教育越來越火爆,最近又興起了“超級小班課”模式。所謂超級小班課,指的是大型多人課堂與小班互動模式結合。
在線直播場景下,文字互動作為其中重要的一環,是聊天室的典型應用場景。但在超級小班課的模式下,常規的聊天室系統卻存在各種各樣的問題,不管是建立多個聊天室,還是單個聊天室進行消息過濾,都存在一些嚴重的問題。
網易雲信首創的聊天室標簽功能,完美支持了上述業務場景,基於聊天室標簽,我們可以靈活地支持聊天室消息定向收發、聊天室權限定向管理、聊天室成員定向查詢等個性化功能,真正實現大型直播下多場景的分組互動,比如對學生進行分組標簽后,方便進行因材施教;分小組討論,小組間內部討論和組間 PK 等等。
如上圖,展示了超級小班課的一個場景:1 個主講教師+ N 個互動小班+ N 個助教,所有學生被划分成了一個一個的小班,由對應的助教完成預習提醒、課后答疑、作業監督、學員學習情況反饋等工作,同時又接收來自主講老師的直播畫面,做到了大課的規模,小課的效果。
總結
以上,就是本文的全部分享,主要介紹了網易雲信構建一個大型聊天室系統的主要技術以及架構原理。任何系統的搭建都不是一蹴而就的,雲信也會繼續打磨底層技術,就像引入 WE-CAN 來提升網絡傳輸效果,也會繼續豐富完善我們的功能圖譜,如業內首創的聊天室標簽功能等。網易雲信將持續在 IM 領域深耕,為各種場景和行業的用戶提供最優質的服務。
作者介紹
曹佳俊,網易雲信資深服務端開發工程師,中科院研究生畢業后加入網易,一直在網易雲信負責 IM 服務器相關的開發工作。對 IM 系統構建以及相關中間件的開發有豐富的實戰經驗。