天天看點

「後端」揭秘百度IM消息中台的全量使用者消息推送技術改造實踐

作者:架構思考
本文内容由百度技術團隊分享,原題“基于公共信箱的全量消息實作”,為了幫助了解,有較多修訂、内容重組和重新排版。

1、引言

百度的IM消息中台為百度APP以及廠内百度系産品提供即時通訊的能力,提供包括私聊、群聊、聊天室、直播彈幕等使用者溝通場景,并幫助業務通過消息推送觸達使用者。如今,百度APP新增了一種需要以“低使用者打擾”的形式觸達全量使用者的場景需求,而現有的IM消息中台主要是基于使用者“私有信箱”通知拆分的機制(通俗了說也就是IM裡的“擴散寫”),是以如果不進行改造,是很難低成本、高時效的滿足該場景訴求。

基于上述問題,本文介紹了百度現有IM消息中台系統的主要組成,并對比多種實作方案的優劣,以“公有信箱”通知讀擴散的技術方案對現有IM消息中台系統進行改造,進而達成了低成本、高時效地實作全量使用者通知推送需求。

「後端」揭秘百度IM消息中台的全量使用者消息推送技術改造實踐

2、全量使用者消息推送需求背景

百度APP新增了需要通過IM實時通知觸達全量使用者的訴求,比如2022年12月7日解除疫情管控結束後,将經過篩選的官方政策解讀、專題彙總、知識科普、實用工具類介紹等資訊,通過官方号“x度小助手”下發觸達到百度APP使用者,進而來有效展現人文關懷,提高使用者粘性。在以IM消息服務進行全量使用者消息觸達時,需要滿足以下訴求:

「後端」揭秘百度IM消息中台的全量使用者消息推送技術改造實踐

具體就是:

1)在觸達範圍上:希望盡量擴大使用者觸達範圍,包括百度APP月活使用者、以及非月活使用者但是近期新注冊或登入的使用者;

2)在時效上:一次全量觸達,希望短時間内完成(比如小時級、甚至分鐘級),搶占時效性;

3)在使用者打擾方面:消息觸達不能給使用者帶來較大的打擾,每次消息下發,隻觸達一次,不能重複打擾使用者(但是需要保留回訪入口,滿足使用者二次檢視的訴求)。

3、現有IM消息中台的技術痛點

我們現有的IM(即時通訊)服務中,每個IM使用者對應一個使用者信箱。基于現有的IM技術實作方案,如果想完成全量使用者的消息觸達,需要把消息推送到每個使用者的信箱(也就是IM中的擴散寫)。這樣的話,要完成6億以上的消息寫入(假定每條占用存儲4KB,每秒寫入2W條消息),在消息寫入時效性以及存儲資源消耗上,都是很難接受的。且現有的基于使用者私有信箱的方案,在同時支援多條全量使用者通知消息的場景下,擴充性也較差。基于上述需求背景和技術痛點,我們本次的改造目的,就是要找到一種技術方案,進而在特定業務場景下通過改造後的消息服務,低成本、高時效的給全量使用者推送内容一緻的消息通知。

4、現有IM消息中台的主要技術實作

在讨論改造方案前,我們有必要介紹一下目前IM消息系統的現狀,包括消息系統的組成、通知拉取模式、使用者信箱等。

4.1 消息系統組成

從普通使用者的直覺體驗上看,一個IM系統可以包括如下元素:

1)使用者主體;

2)使用者賬号;

3)賬号關系;

4)聊天會話;

5)聊天消息。

用自然語言串一下以上元素就是:

1)“使用者主體”具有“使用者賬号”;

2)“使用者主體”具有頭像、昵稱等使用者屬性;

3)“使用者主體”通過“使用者賬号”登入IM系統,進行聊天;

4)“使用者賬号”之間的關注、屏蔽、免打擾等構成“使用者關系”;

5)通過使用者之間的互動環節可以産生“聊天消息”;

6)聊天記錄構成了一個“聊天會話”。

下面這張圖可能更直覺一些:

「後端」揭秘百度IM消息中台的全量使用者消息推送技術改造實踐

從內建消息服務的業務方角度看:

1)一個IM系統可以包括消息用戶端(消息用戶端UI元件、消息SDK)和消息服務端;

2)IM消息可以作為一種服務,嵌入到各業務系統中,為業務系統提供“實時互動”能力;

3)業務通過內建IM服務,提升其使用者體驗;

4)業務APP內建IM SDK,通過IM SDK與IM Server互動,完成使用者上行通訊能力;

5)業務APP Server通過與IM Server互動,完成通知下行觸達使用者。

下圖為一個內建了IM SDK的業務架構圖:

「後端」揭秘百度IM消息中台的全量使用者消息推送技術改造實踐

從使用場景來看,消息包括:

1)“私信消息”(包括使用者上下行消息);

2)“通知消息”(業務方給使用者推送的下行消息);

3)“群聊”、“聊天室”;

4)“直播間彈幕”等。

4.2 消息的通知拉取模式

百度的IM消息系統,采用通知拉取(notify-pull)模式來感覺新消息、拉取新消息。

IM SDK登入時,與IM 服務端建立長連接配接(LCS, Long Connect Service),使用者有新的消息時,通過長連接配接下發notify,實時通知使用者的IM SDK。

實時notify不寫使用者信箱,因為noitfy不是消息(可以了解為提醒線上使用者有新消息的信号),IM SDK根據這個信号,來服務端拉取消息。

業務方server或者其他使用者給該使用者發送消息後,經過IM業務處理子產品,把消息寫入接收者信箱,IM Server會根據使用者的登入和路由資訊,給消息接收者(私信場景下也包括“消息發送者”,用于消息的多端同步)發送新消息notify,接收到notify的IM裝置,通過IM SDK來IM Server端拉取(pull)消息。

4.3 使用者信箱介紹

為了暫存尚未拉取到IM SDK本地的離線消息,需要對消息進行服務端存儲,而消息的離線存儲是通過消息信箱服務完成的。

目前百度的IM使用者消息信箱主要包括:

1)使用者私有信箱;

2)群公共信箱(非下文提到的使用者公共信箱);

3)直播間彈幕mcast等。

使用者信箱通過“消息所屬應用”+“IM辨別使用者的唯一ID”來辨別。

就一條消息而言:消息參與者有“消息發送者”和“消息接收者”,消息收發雙方的信箱都是互相獨立的(假設發送方删除了自己信箱的某一條消息,不會影響消息接受者信箱的消息)。

對于有檢視曆史消息訴求的一方來說:消息需要入該方的信箱,比如使用者之間的私信(也就是一對一單聊)消息需要入發送者和接收者的信箱。

而對于全量使用者消息通知的場景:消息不需要存儲發送者信箱,而隻需要存接收者的信箱。而使用者的信箱排序,是基于信箱Timeline(詳見《現代IM系統中聊天消息的同步和存儲方案探讨》)。即消息在信箱内部基于時間線存儲,每條消息對應一個unix 微秒時間戳(如第一條消息1679757323320865),使用者進行信箱拉取時,基于時間範圍正序或者逆序拉取。

如下為信箱Timeline的示例:

「後端」揭秘百度IM消息中台的全量使用者消息推送技術改造實踐

使用者信箱中的每一條消息記錄都包含四個主要部分:

1)“消息ID”;

2)“消息使用者辨別”;

3)“消息通用屬性”;

4)“消息業務屬性”。

下面詳細介紹以上四個部分:

1)消息ID:為unix微秒時間戳,不需要全局唯一,隻需要特定使用者信箱範圍内唯一即可;

2)消息使用者辨別:包括from_uid、to_uid、contacter;

3)消息通用屬性:包括create_time、expire、is_read;

4)消息業務屬性:包括category、type、priority、business_type、APP_id、msgkey、content等。

如下為一條消息記錄示例:

「後端」揭秘百度IM消息中台的全量使用者消息推送技術改造實踐

5、全量使用者消息推送技術方案選型

5.1 需求分析

目前百度的IM消息推送機制中,主要支援:

1)單點傳播:消息推送方式,每次給一個使用者推送一條消息;

2)批量單點傳播:每次給小範圍使用者推送消息,比如30個;

3)廣播:基于關注關系的推送,如給全量粉絲推送。

上述三種消息推送機制推送的消息,均需要存儲服務端的使用者私有信箱。為了完成百度APP 6億以上全量月活使用者的消息推送,目前有三種可選的方案,接下來我們逐一分析。

5.2 方案1:全流程從通知入口推送

該種方式下:需要擷取全量的月活使用者清單,經過IM Server推送入口,給每一個使用者推送疫情相關通知。

該通知寫入到使用者信箱時:

1)若使用者線上,在實時拉取該通知;

2)若使用者離線,再下次登入IM服務時,拉取離線通知。

該種方案下:推送行為會覆寫IM的全流程,推送的通知會進入每個月活使用者的私有信箱,服務壓力大。其中增量使用者不會收到通知推送(這裡增量使用者指的是不在月活使用者清單的使用者)。

5.3 方案2:跳過通知入口直接寫信箱

該種方式跳過IM消息推送流程中的中間環節,直接把通知消息寫入使用者信箱。

由于跳過了中間流程直接寫入信箱,通知寫入速度主要取決于信箱底層存儲的壓力承受情況。

該種方案下,同方案1一樣,無法給使用者發送實時通知,依賴使用者IM SDK的主動消息拉取(斷鍊後重新登入/新消息提醒拉取),無法給增量使用者發送通知。

該方案由于跳過中間環節直接寫信箱,風險較大,無法直接提供給業務方使用,不建議如此操作。

5.4 方案3:公有信箱實作機制

該種公有信箱機制的邏輯是把通知消息寫入“公共信箱”。在使用者消息拉取時,合并“使用者私信信箱”+“公共信箱”的消息。

5.5 三種方案比較

「後端」揭秘百度IM消息中台的全量使用者消息推送技術改造實踐

方案1和2都是寫擴散方式,基于現有“使用者私有信箱”的機制,把通知消息寫入每個接收通知的使用者私有信箱。

方案2與方案1的差别主要是跳過了消息中間流程,可以避免因為中間環節負載瓶頸導緻整體消息寫入速度過低。

方案3是讀擴散方式,消息不用再寫入接收通知的使用者私有信箱,而隻需要在公共信箱存儲一份。在使用者拉取消息時,實時拉取公共信箱的消息。方案③中可以采用記憶體緩存方案,解決對公共信箱的讀壓力。

本質上來說:方案3與方案前兩種相比,是用讀成本(CPU)換寫成本(存儲)。

6、基于公有信箱技術方案的全量使用者消息推送實作

6.1 概述

基于上述方案3的思路,我們進行基于公有信箱的全量消息設計與實作。

該種方案中包含兩個主要流程:

1)全量消息的管理;

2)使用者私有+公有信箱的拉取。

6.2 全量消息的管理

全量消息管理主要分為:

1)營運O端操作平台:複用營運消息平台;

2)全量消息處理服務:複用IM服務的連接配接層、邏輯處理層、信箱代理、信箱處理。

營運O端平台為營運同學提供可視化界面,可以對全量消息進行編輯、預釋出、釋出、修改、停止、撤回等操作。

具體就是:

1)接入層:對接營運O端,進行參數校驗、轉發IM後端邏輯處理子產品;

2)邏輯處理層:進行全量消息的建立、修改、停止、删除、撤回等邏輯操作;

3)信箱代理層:複用IM服務的信箱CRUD操作;信箱存儲層公共信箱的底層存儲。

全量消息管理流程:

「後端」揭秘百度IM消息中台的全量使用者消息推送技術改造實踐

6.3 使用者信箱拉取

使用者通過IM SDK,以長連接配接的方式,在邏輯處理層進行消息拉拉取。

在使用者拉取信箱消息時,需要對“使用者個人信箱”和“公有信箱”進行合并。于是每次使用者信箱拉取,都需要進行信箱的合并拉取。

6.3.1)公共信箱記憶體緩存機制:

百度APP的IM使用者,在IM SDK登入時需要拉取信箱中的消息。每次消息拉取時,需要檢查公共信箱中是否有消息。

是以,公共信箱需要能抗住日常和峰值流量(拉取峰值為4.7Wqps)。為了防止流量擊穿,流量打到底層的持久化公共信箱MYSQL存儲,我們設計了基于記憶體的公共信箱緩存機制。同時公共信箱内容變化時,也要實時(或者在能容忍的範圍内做到準實時)變更記憶體緩存信箱中的消息,我們采用Bthread定期輪詢持久化公共信箱,更新記憶體公共信箱,輪詢間隔可配置(比如設定1秒)。

6.3.2)分級釋出機制:

同時,在邏輯層實作白名單機制,支援全量消息在“預釋出”狀态下,僅對白名單使用者可見,進而達到分級驗證的效果。白名單的使用者清單通過邏輯處理成的配置加載,也支援通過CURL請求動态修改白名單的配置。

「後端」揭秘百度IM消息中台的全量使用者消息推送技術改造實踐

7、基于公有信箱技術方案的技術挑戰

公有信箱的技術方案,需要解決如下問題:

「後端」揭秘百度IM消息中台的全量使用者消息推送技術改造實踐

8、基于公有信箱技術方案的優缺點總結

8.1 優點

以公共信箱的方式,實作全量使用者消息分發,具有:“分發速度快”、“資源成本低”的特點。

「後端」揭秘百度IM消息中台的全量使用者消息推送技術改造實踐

8.2 缺點

但公共信箱的方式也存在一定的局限性。

8.2.1)不适用于個性化要求高的場景:

由于消息在公共信箱隻存儲一份,下發消息内容固定,無法很大程度下,下發個性化消息(當然也不是一定無法下發個性化的消息,可以通過在公共信箱存儲消息模闆,根據拉取消息的使用者ID擷取個性化資訊,在消息拉取時,臨時拼裝消息,這樣就增大了消息拉取時的代價)。

8.2.2)不适用于實時消息提醒場景:

1)從業務場景上看:全量消息優先級低,不需要在全量生效的瞬間讓使用者感覺。

2)從實作上看:全量消息實時消息提醒成本高。因為實時消息提醒Notify,需要以類似單點傳播的形式實時通知使用者。和單點傳播的差別是,Notify不用觸達離線使用者,也就是不用寫使用者信箱,隻需實時觸達線上使用者。

3)從系統壓力看:全量線上使用者均收到實時新消息提醒,會帶來信箱拉取請求的瞬時流量(手機百度IM SDK長連接配接峰值線上1550W,假定新消息提醒在瞬間下發,同時線上使用者信箱拉取請求,會把db打挂的)。

9、基于公有信箱技術方案的落地實施效果

全量消息目前已經在百度APP得到應用,包括:重大通知的下發;百度APP功能更新介紹通知;消息的撤回,後續還将推廣到其他的矩陣APP的全量通知推送場景。

舉個具體的例子:22年Q4宣布疫情解封時,利用全量消息推送,低成本、高時效的完成3條“疫情解封專項”全量消息下發。

「後端」揭秘百度IM消息中台的全量使用者消息推送技術改造實踐

在這個例子中,三次全量消息下發,到達資料在2億+(該值小于月活的6億+),主要因為幾個原因:

1)本次全量消息有效期僅3天左右,全量消息有效期内登入IM SDK的使用者才有機會拉到全量消息;

2)本次下發使用了新的消息展示模闆,是以限制了拉取全量消息的百度APP版本,隻有高版本百度APP可以拉到;

3)本次全量消息,限制了僅有百度APP登入使用者拉取。

10、未來展望

本文介紹了現有IM消息中台系統,并通過公有信箱技術方案的改造,達成了低成本、高分發速度完成全量使用者消息下發的設計、實作與應用。在全量使用者消息應用方面,除了業務上的使用,後續也可以用于廣播消息、批量單點傳播消息的撤回。比如由于誤操作發送了廣播消息,使用者已經把廣播消息拉到了端,并持久化到端,這是可以“以全量消息的方式,下發删除指令”,删除已經緩存到端的垃圾消息。我們希望,通過消息系統持續不斷優化,為更多的業務提供低成本、高穩定性的即時通訊能力。

文章來源:https://segmentfault.com/a/1190000043831961

繼續閱讀