日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

深度剖析「圈组」消息系统设计 | 「圈组」技术系列文章

發布時間:2025/3/8 windows 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深度剖析「圈组」消息系统设计 | 「圈组」技术系列文章 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

導讀:

網易云信新晉的 IM 頂流產品「圈組」出道后獲取到了極大的關注,很多云信的客戶在接入的同時對于「圈組」的底層技術細節和原理也非常關注,為此,我們決定推出云信「圈組」相關的系列技術文章,分享網易云信在「圈組」技術設計上的一些思考。

文|曹佳俊 網易云信資深服務器開發工程師

一、技術選型

在介紹「圈組」的技術細節之前,我們先分析一下圈組的技術特點(了解「圈組」可閱讀下面兩篇文章:行業洞見丨Discord 狂奔的背后與網易云信「圈組」的長期主義?或?正式出「圈」丨網易云信圈組的近謀與遠慮),「圈組」產品最大的特點是什么?首先是?server/channel 的二級結構;其次是構建在二級結構之上的大規模社群(單個 server 數十萬甚至上百萬成員),以及使用復雜的身份組系統來管理如此規模的社群組織和成員。

那么對于這樣一個新穎的 IM 系統,在技術上應該如何實現呢?

一種簡單的思路是改造已有的 IM 系統,對于「圈組」這樣的類 Discord 社群,第一個思路是拓展我們的群組功能,猛一看在很多方面確實挺像的,我們做了個簡單的對比:

從上面的表格可以看到,「圈組」和群組最大的不同,一個是容量的區別,一個是二級結構。其他的諸如身份組、個性化推送策略,似乎只要適配的做一下就可以了,那么是不是只要想辦法提升一下群組的容量,再在業務層封裝一下二級結構就可以了呢?答案顯然是否定的,或者至少說基于群組去擴展不是一個很好的想法。

首先是二級結構,在類 Discord 的二級結構中,成員的管理在 server 層,而 channel 成員是繼承自 server 的,而且在 channel 之上還有很多可見性的配置(云信「圈組」提供了黑白名單機制,Discord 則提供了查看頻道權限),在這種機制之下,任何 server 層面的成員變動,都可能影響全部或者部分頻道的成員列表;面對這種復雜的結構,群組有兩種思路去實現,一種是 N 個群,邏輯上隸屬于同一個 server;還有一種是一個群映射為一個 server。不管哪種方式,先不說消息投遞這塊的邏輯,僅成員管理上邏輯的耦合和交織的復雜性,足以勸退任何人。

其次是容量,常規的群組的容量一般只有數百,最多可以擴展到數千,對于群組成員的管理,我們一般采取全量+增量同步相結合的方案,客戶端和服務器映射到相同的群組鏡像(群信息+群成員等),此時很多操作,例如群成員的展示、檢索,消息的艾特等,都可以基于純客戶端進行。而「圈組」要求幾十萬甚至上百萬的容量,顯然客戶端無法一次性獲取到所有成員,如果你一次性加入多個 server,那成員的數量將更加膨脹。因此在「圈組」這種大規模社群的設計中,很多邏輯都會轉向云端,此時不管是 SDK 還是服務器,均需要修改原有的設計邏輯。

此外,大規模社群帶來的是消息爆炸,在原有的群組設計中,假設一個人同時加入了 1000 個群,那么這 1000 個群內的所有消息均會在第一時間下發給給客戶端,但是在一般的業務場景中,不會所有的群都同時活躍,假設這 1000 個群變成了 1000 個服務器/頻道,作為一種社群組織,同時活躍的可能性將大大增加,而且每個服務器/頻道的人數遠遠超過普通的群組,疊加之后帶來的消息爆炸現象在原有的群組體系中將帶來極大的壓力,壓力包括多方面:首先是海量消息的存儲壓力,其次是海量消息在線廣播/離線消息推送帶來的帶寬和服務器壓力,以及客戶端在面對大量消息沖擊時如何有效地接受和合理的展示。

除了容量和二級結構,包括身份組、成員管理、個性化推送策略等等,是否真的適合在群組中添加這些復雜邏輯呢,強行綁定在一起會不會既沒有一個好用的類 Discord 平臺,也使得原始的群組功能繁雜,反而降低了易用性呢?

經過上面的一些分析,我們基本可以得出一個結論,在已有的群組基礎上擴展來實現一個類 Discord 功能的社群,顯然不是一個很好的思路,那么還有其他“捷徑”嗎?聊天室也是一個潛在的選項,聊天室的一大特點就是支持超大規模同時在線(參考文章:網易實踐|千萬級在線直播彈幕方案),容量似乎已經不是問題,但是當考慮添加其他一些強社交關系的特性時(如成員、身份組等)就顯得有點為難了,聊天室本身就是來去自如的一個開放空間,這個和圈組的產品本身定位互相沖突的,因此基于聊天室擴展的方案也基本 pass 掉了。

二、技術難點

基于上述種種的思考和討論,最終網易云信選擇脫離已有 IM 體系,從零研發一套全新的社群方案「圈組」,「圈組」不是一個簡單的 IM 功能,而是一套可以獨立運行的 IM 系統,經過上面的討論,相信大家對「圈組」本身的技術特點和難點也有所理解,可以歸納為以下幾點:

  • 二級結構下成員無上限的社交關系系統設計。

  • 超大社群下消息系統設計。

  • 復雜高效的身份組系統設計。

  • 三、「圈組」消息系統技術剖析

    本文將針對上述三點之中的第二點:超大社群下的消息系統設計,分享我們的一些技術設計原理和經驗。

    (一) 「圈組」整體架構?

    ?

    上面展示了「圈組」服務整體的架構,可以看到整個「圈組」服務是一個分層的架構,首先是接入層,包括 LBS 服務和長鏈接服務器以及 API 網關,對應客戶端 SDK 和用戶服務器;后面是網絡層,包括大網 WE-CAN 和協議路由服務;其次是服務層,劃分了多個服務模塊,每個模塊都包括多個微服務;最后是基礎設施

    ?(二)消息系統架構?

    這其中和消息系統相關聯的包括接入層、網絡層、以及后端的登錄/訂閱/消息/檢索等模塊,基本架構如下:

    下文我們將對消息系統中各模塊分別展開介紹。

    ?(三)消息系統技術細節?

    消息系統中第一個要討論的點就是消息的存儲和分發方式,包括在線廣播、離線推送、歷史消息三個維度。

    • 在線廣播

    對于一般的群組來說,在線廣播的一般過程是這樣的:依次查詢群組里的所有人的在線狀態,如果在線,則將消息發送給對應的長鏈接服務器。顯然這種機制無法復制到「圈組」,因為在「圈組」的一個服務器里可能存在超過 100w 的人;此外,聊天室的廣播模式也不能直接復用,因為在聊天室架構中,每個長鏈接映射到一個聊天室,因此當你登錄到某個聊天室的時候,你只會收到該聊天室的消息,而對于「圈組」來說,每個用戶會同時加入多個服務器/頻道,而且會同時收到多個服務器/頻道的消息。

    針對「圈組」的上述特點,云信設計了消息訂閱模式,也就是用戶登錄之后,需要訂閱感興趣的相關服務器/頻道,服務器會記錄下這個訂閱信息,當有新消息的時候,服務器通過訂閱關系(而不是在線狀態)查詢到需要廣播的列表,通過這種方式就不再需要遍歷服務器/頻道里的所有用戶;

    但是當一個服務器/頻道里在線人數非常多的時候,這個訂閱關系仍然是巨大的,為此云信設計了一種兩層訂閱模型,所有的訂閱關系會保存在長鏈接服務器上(QChatLink/QChatWebLink),同時長鏈接服務器會定時發送心跳給后端的訂閱服務器,心跳信息相比原始的訂閱信息會大大簡化,比如長鏈接服務器上會記錄賬號 A 訂閱了某個頻道 A 的消息,如果有 1w 個賬號,則有 1w 條訂閱記錄,而心跳信息里只會上報有 1w 個人訂閱了某個頻道 A 的消息,具體的賬號列表則被精簡掉了;當一條消息需要廣播時,消息服務會訪問訂閱服務,獲取到該服務器/頻道被訂閱的長鏈接服務器列表,并依次給該列表中的長鏈接服務器發送消息下發通知,長鏈接服務器收到通知后會根據訂閱詳情再廣播給所有客戶端。

    此外,我們還提供了多種訂閱類型,當你非常關心某個頻道消息時(比如頁面正停留在該頻道),此時你可以訂閱該頻道的消息;對于其他頻道,如果你僅僅需要知道該頻道有多少條未讀消息(或者有無未讀消息),則可以選擇訂閱該頻道的未讀計數(或者未讀狀態),此時服務下發時僅會廣播精簡的消息體用于維護客戶端未讀計數,并且當未讀計數達到一定閾值之后(比如 99+),服務器可以選擇不再下發任何通知消息而不影響用戶體驗。

    通過上文介紹的消息訂閱模型,極大地提高了超大型的圈組頻道/服務器消息在線廣播的效率,降低了服務器壓力;除此之外,我們還設計了針對小型頻道的特殊策略,對于小型頻道,即使不訂閱,服務器也會下發消息通知給頻道里所有人,從而減輕端側消息訂閱模型的維護成本;針對消息訂閱機制本身,后續我們也會根據不同的業務場景,提供更多一站式的策略來幫助降低接入成本,提升整體的易用性。

    • 離線推送

    在強社交的場景下,離線推送對于維持用戶粘性+提升產品體驗有很大的作用。從技術角度看的話,主要解決2個問題,第一個是超大型服務器/頻道的消息推送的效率問題;另外一個是提供足夠豐富的推送策略來幫助 C 端用戶,避免被過量的推送消息給打擾。

    針對第一個問題,云信「圈組」針對不同規模的服務器/頻道采取了不同的策略,對于小型頻道,采用類似于群組的消息推送模型;而對于大型頻道,對于每一條需要推送的消息,會根據目標用戶的 ID 進行任務分片,多個節點并行操作,提高推送效率。此外分片會采用一致性策略,保證單個用戶固定為某些節點,從而提高緩存命中效率。

    針對第二個問題,云信「圈組」的推送策略可以用以下幾句話來描述:

    • 既關注促活,又保證不打擾

    • 大型 server 是游樂場,只推送與用戶相關的重要消息(如 @消息)

    • 小型 server 是與朋友相處的小天地,支持消息的全部推送

    并且未來用戶還可以自定義消息的高低優先級,并搭配不同的推送配置(如不同的免打擾配置等):

    ?

    • 歷史消息

    歷史消息的存儲在「圈組」的場景中也需要一些特別的設計。同樣以群組為例,一般來說消息的存儲方式有兩種,寫擴散和讀擴散,在小型的群組或者多人會話中,寫擴散模式可以簡化設計,但是當群組規模擴大到一定程度(如萬人群),讀擴散就成了選擇,而對于「圈組」這種單個服務器可能上百萬人的“群組”中,除了常規的讀擴散之外,我們還設計了多級緩存的結構來應對海量的讀請求,基本的存儲架構大致如下:

    消息的存儲主要包括兩部分,一部分是消息本身,還有一部分是未讀計數

    首先是寫入,對于上述兩者,我們都會使用中心化的緩存服務器來存儲最近的數據,并使用異步+批量+聚合等手段,通過 MQ 異步落庫,從而平衡寫入效率(單條寫入性能低)和寫入讀取延遲(異步寫入有延遲)的問題,并且針對不同數據類型的特點,我們也選擇了不同的存儲方案(歷史消息使用分布式時間序列數據庫,未讀計數使用分布式 k-v 數據庫),最大化地提升消息存儲和查詢的性能和效率。

    有寫就有讀,針對讀取操作,所有最近的消息和未讀計數均會存儲在中心化緩存中,并通過先進先出和緩存過期等不同的策略來確保緩存中存儲的永遠是最新和最熱的數據;此外對于消息 ID 和消息內容本身,中心化緩存中也會有不同的數據結構和過期策略,來平衡緩存命中率和緩存容量消耗;當緩存過期了,如果有關聯的讀寫請求,將會觸發緩存的重建,以保證緩存的命中率始終保持在較高水位;最后,當有高頻的讀請求,還會觸發熱點 cache 的檢測,并將一部分讀請求下沉到各個計算節點的內存中,以應對突發流量的沖擊。

    上述針對「圈組」的特別設計,消息存儲系統可以應對幾十數百人的小型圈組頻道,也可以從容應對上百萬的超大型頻道。

    • 特色功能

    說完了消息系統的核心存儲和分發模式,「圈組」的消息系統還提供了很多額外的特色功能:

    • 消息更新:所謂的消息更新是指消息發送之后還允許修改,消息撤回和刪除被認為是消息更新的一種特殊狀態,這在管理一個大型社群中的消息時有著重要的作用。

    • 消息互動(即將推出):「圈組」提供了比 Discord 的消息回復更強的 thread 聊天功能,不同于子區是單獨開辟一塊空間,thread 聊天可以讓你在復雜的消息流中自動篩選出關于某一個話題的所有關聯消息。「圈組」也提供了快捷評論的功能,你可以給一條消息添加各種自定義的表情,這在大型的頻道中幾乎是剛需,因為你再也不用忍受消息爆炸了。云信針對大型頻道的快捷評論也做了特殊的優化,當一條消息獲得大家的一致喜愛時,頻道里所有人都可以給他點一個😊或者👍,數量不設上限。

    • 消息檢索(敬請期待):「圈組」的檢索系統也是一大特色,消息檢索自然是其中重要的一環,消息檢索將助你在繁雜的消息流中尋找到你想要的消息

    • 第三方回調和抄送:這充分體現了「圈組」作為云信 PaaS 平臺產品的一大特點,通過第三方回調和抄送,你可以在各種各樣的操作(如發消息、拉人踢人、修改信息等)的 before 和 after,植入任何你想要的邏輯,譬如機器人、內容審計等(當然云信也有安全通一站式內容安全解決方案,可以按需選擇)。

    四、總結

    說了這么多,云信「圈組」作為一款全新設計的產品,沒有任何歷史包袱的限制(但是卻可以充分吸收歷史優點),你可以使用它構建一個類 Discord 產品,或者任何你想得到的社交/娛樂/游戲產品,歡迎大家選擇。

    ?作者介紹?

    曹佳俊,網易云信資深服務器開發工程師,畢業于中國科學院,碩士畢業后加入網易,負責云信 IM/RTC 信令等業務的服務器開發。專注于即時通訊、RTC 信令以及相關中間件等技術,是云信開源項目 Camellia 的作者。

    總結

    以上是生活随笔為你收集整理的深度剖析「圈组」消息系统设计 | 「圈组」技术系列文章的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。