阿里IM技術(shù)分享(六):閑魚億級IM消息系統(tǒng)的離線推送到達(dá)率優(yōu)化

本文由阿里閑魚技術(shù)團(tuán)隊逸昂分享,原題“消息鏈路優(yōu)化之弱感知鏈路優(yōu)化”,有修訂和改動,感謝作者的分享。
1、引言
閑魚的IM消息系統(tǒng)作為買家與賣家的溝通工具,增進(jìn)理解、促進(jìn)信任,對閑魚的商品成交有重要的價值,是提升用戶體驗最關(guān)鍵的環(huán)節(jié)。
然而,隨著業(yè)務(wù)體量的快速增長,當(dāng)前這套消息系統(tǒng)正面臨著諸多急待解決的問題。
以下幾個問題典型最為典型:
1)在線消息的體驗提升;
2)離線推送的到達(dá)率;
3)消息玩法與消息底層系統(tǒng)的耦合過強。
經(jīng)過評估,我們認(rèn)為現(xiàn)階段離線推送的到達(dá)率問題最為關(guān)鍵,對用戶體驗影響較大。
本文將要分享的是閑魚IM消息在解決離線推送的到達(dá)率方面的技術(shù)實踐,內(nèi)容包括問題分析和技術(shù)優(yōu)化思路等,希望能帶給你啟發(fā)。

學(xué)習(xí)交流:
- 即時通訊/推送技術(shù)開發(fā)交流5群:215477170?[推薦]
- 移動端IM開發(fā)入門文章:《新手入門一篇就夠:從零開發(fā)移動端IM》
- 開源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK?
(本文已同步發(fā)布于:http://www.52im.net/thread-3748-1-1.html?)
2、系列文章
本文是系列文章的第6篇,總目錄如下:
《阿里IM技術(shù)分享(一):企業(yè)級IM王者——釘釘在后端架構(gòu)上的過人之處》
《阿里IM技術(shù)分享(二):閑魚IM基于Flutter的移動端跨端改造實踐》
《阿里IM技術(shù)分享(三):閑魚億級IM消息系統(tǒng)的架構(gòu)演進(jìn)之路》
《阿里IM技術(shù)分享(四):閑魚億級IM消息系統(tǒng)的可靠投遞優(yōu)化實踐》
《阿里IM技術(shù)分享(五):閑魚億級IM消息系統(tǒng)的及時性優(yōu)化實踐》
《阿里IM技術(shù)分享(六):閑魚億級IM消息系統(tǒng)的離線推送到達(dá)率優(yōu)化》(* 本文)
3、通信鏈路類型的劃分
從數(shù)據(jù)通信鏈接的技術(shù)角度,我們根據(jù)閑魚客戶端是否在線,將整體消息鏈路大致分為強感知鏈路和弱感知鏈路。
強感知鏈路由以下子系統(tǒng)或模塊:
1)發(fā)送方客戶端;
2)idleapi-message(閑魚的消息網(wǎng)關(guān));
3)heracles(閑魚的消息底層服務(wù));
4)accs(阿里自研的長連接通道);
5)接收方客戶端組成。
整條鏈路的核心指標(biāo)在于端到端延遲和消息到達(dá)率。
強感知鏈路中的雙方都是在線的,消息到達(dá)客戶端就可以保證接收方感知到。強感知鏈路的主要痛點在消息的端到端延遲。
弱感知鏈路與強感知鏈路的主要不同在于:弱感知鏈路的接收方是離線的,需要依賴離線推送這樣的方式送達(dá)。
因此弱感知鏈路的用戶感知度不強,其核心指標(biāo)在于消息的到達(dá)率,而非延遲。
所以當(dāng)前階段,優(yōu)化弱感知鏈路的重點也就是提升離線消息的到達(dá)率。換句話說,提升離線消息到達(dá)率問題,也就是優(yōu)化弱感知鏈路本身。
4、消息系統(tǒng)架構(gòu)概覽
下圖一張整個IM消息系統(tǒng)的架構(gòu)圖,感受下整體鏈路:

如上圖所示,各主要組件和子系統(tǒng)分工如下:
1)HSF是一個遠(yuǎn)程服務(wù)框架,是dubbo的內(nèi)部版本;
2)tair是阿里自研的分布式緩存框架,支持 memcached、Redis、LevelDB 等不同存儲引擎;
3)agoo是阿里的離線推送中臺,負(fù)責(zé)整合不同廠商的離線推送通道,向集團(tuán)用戶提供一個統(tǒng)一的離線推送服務(wù);
4)accs是阿里自研的長連接通道,為客戶端、服務(wù)端的實時雙向交互提供便利;
5)lindorm是阿里自研的NoSQL產(chǎn)品,與HBase有異曲同工之妙;
6)域環(huán)是閑魚消息優(yōu)化性能的核心結(jié)構(gòu),用來存儲用戶最新的若干條消息。
強感知鏈路和弱感知鏈路在通道選擇上是不同的:
1)強感知鏈路使用accs這個在線通道;
2)弱感知鏈路使用agoo這個離線通道。
5、弱感知鏈路到底怎么定義
通俗了說,弱感知鏈路指的就是離線消息推送系統(tǒng)。
相比較于在線消息和端內(nèi)推送(也就是上面說的強感知鏈路),離線推送難以確保被用戶感知到。
典型的情況包括:
1)未發(fā)送到用戶設(shè)備:即推送未送達(dá)用戶設(shè)備,這種情況可以從通道的返回分析;
2)發(fā)送到用戶設(shè)備但沒有展示到系統(tǒng)通知欄:閑魚曾遇到通道返回成功,但是用戶未看到推送的案例;
3)展示到通知欄,并被系統(tǒng)折疊:不同安卓廠商對推送的折疊策略不同,被折疊后,需用戶主動展開才能看到內(nèi)容,觸達(dá)效果明顯變差;
4)展示到通知欄,并被用戶忽略:離線推送的點擊率相比于在線推送更低。
針對“1)未發(fā)送到用戶設(shè)備”,原因有:
1)離線通道的token失效;
2)參數(shù)錯誤;
3)用戶關(guān)閉應(yīng)用通知;
4)用戶已卸載等。
針對“3)展示到通知欄,并被系統(tǒng)折疊”,原因有:
1)通知的點擊率;
2)應(yīng)用在廠商處的權(quán)重;
3)推送的數(shù)量等。
針對“4)展示到通知欄,并被用戶忽略”,原因有:
1)用戶不愿意查看推送;
2)用戶看到了推送,但是對內(nèi)容不感興趣;
3)用戶在忙別的事,無暇處理。
總之:以上這些離線消息推送場景,對于用戶來說感知度不高,我們也便稱之為弱感知鏈路。
6、弱感知鏈路的邏輯構(gòu)成
我們的弱感知鏈路分為3部分,即:
1)系統(tǒng);
2)通道;
3)用戶。
共包含了Hermes、agoo、廠商、設(shè)備、用戶、承接頁這幾個環(huán)節(jié)。具體如下圖所示。

從推送的產(chǎn)生到用戶最終進(jìn)入APP,共分為如下幾個步驟:
步驟1:Hermes是閑魚的用戶觸達(dá)系統(tǒng),負(fù)責(zé)人群管理、內(nèi)容管理、時機把控,是整個弱感知鏈路的起點。;
步驟2:agoo是阿里內(nèi)部承接離線推送的中臺,是閑魚離線推送能力的基礎(chǔ);
步驟3:agoo實現(xiàn)離線推送依靠的是廠商的推送通道(如:蘋果的apns通道、Google的fcm通道、及國內(nèi)各廠商的自建通道。;
步驟4:通過廠商的通道,推送最終出現(xiàn)在用戶的設(shè)備上,這是用戶能感知到推送的前提條件;
步驟5:如果用戶剛巧看到這條推送,推送的內(nèi)容也很有趣,在用戶的主動點擊下會喚起APP,打開承接頁,進(jìn)而給用戶展示個性化的商品。
經(jīng)過以上5個步驟,至此弱感知鏈路就完成了使命。
7、弱感知鏈路面臨的具體問題
弱感知鏈路的核心問題在于:
1)推送的消息是否投遞給了用戶;
2)已投遞到的消息用戶是否有感知。
這對應(yīng)推送的兩個階段:
1)推送消息是否已到達(dá)設(shè)備;
2)用戶是否查看推送并點擊。
其中:到達(dá)設(shè)備這個階段是最基礎(chǔ)的,也是本次優(yōu)化的核心。
我們可以將每一步的消息處理量依次平鋪,展開為一張漏斗圖,從而直觀的查看鏈路的瓶頸。
漏斗圖斜率最大的地方是優(yōu)化的重點,差異小的地方不需要優(yōu)化:

通過分析以上漏斗圖,弱感知鏈路的優(yōu)化重點在三個方面:
1)agoo受理率:是指我們發(fā)送推送請到的數(shù)量到可以通過agoo(阿里承接離線推送的中臺)轉(zhuǎn)發(fā)到廠商通道的數(shù)量之間的漏斗;
2)廠商受理率:是指agoo中臺受理的量到廠商返回成功的量之間的漏斗;
3)Push點擊率:也就通過以上通道最終已送到到用戶終端的消息,是否最終轉(zhuǎn)化為用戶的主動“點擊”。
有了優(yōu)化方向,我們來看看優(yōu)化手段吧。
8、我們的技術(shù)優(yōu)化手段
跟隨推送的視角,順著鏈路看一下我們是如何進(jìn)行優(yōu)化的。
8.1 agoo受理率優(yōu)化
用戶的推送,從 Hermes 站點搭乘“班車”,駛向下一站:?agoo。
這是推送經(jīng)歷的第一站。到站一看,傻眼了,只有不到一半的推送到站下車了。這是咋回事嘞?
這就要先說說 agoo 了,調(diào)用 agoo 有兩種方式:
1)指定設(shè)備和客戶端,agoo直接將推送投遞到相應(yīng)的設(shè)備;
2)指定用戶和客戶端,agoo根據(jù)內(nèi)部的轉(zhuǎn)換表,找到用戶對應(yīng)的設(shè)備,再進(jìn)行投遞。
我們的系統(tǒng)不保存用戶的設(shè)備信息。因此,是按照用戶來調(diào)用agoo的。
同時:由于沒有用戶的設(shè)備信息,并不知道用戶是 iOS 客戶端還是 Android 客戶端。工程側(cè)不得不向 iOS 和 Android 都發(fā)送一遍推送。雖然保證了到達(dá),但是,一半的調(diào)用都是無效的。
為了解這個問題:我們使用了agoo的設(shè)備信息。將用戶轉(zhuǎn)換設(shè)備這一階段提前到了調(diào)用 agoo 之前,先明確用戶對應(yīng)的設(shè)備,再指定設(shè)備調(diào)用 agoo,從而避免無效調(diào)用。

agoo調(diào)用方式優(yōu)化后,立刻剔除了無效調(diào)用,agoo受理率有了明顯提升。
至此:我們總算能對 agoo 受理失敗的真正原因做一個高大上的分析了。
根據(jù)統(tǒng)計:推送被 agoo 拒絕的主要原因是——用戶關(guān)閉了通知權(quán)限。同時,我們對 agoo 調(diào)用數(shù)據(jù)的進(jìn)一步分析發(fā)現(xiàn)——有部分用戶找不到對應(yīng)的設(shè)備。 優(yōu)化到此,我們猛然發(fā)現(xiàn)多了兩個問題。
那就繼續(xù)優(yōu)化唄:
1)通知體驗優(yōu)化,引導(dǎo)打開通知權(quán)限;
2)與agoo共建設(shè)備庫,解決設(shè)備轉(zhuǎn)換失敗的問題。
這兩個優(yōu)化方向又是一片新天地,我們擇日再聊。
8.2 廠商推送通道受理率優(yōu)化
推送到達(dá) agoo ,分機型搭乘廠商“專列”,駛向下一站:用戶設(shè)備。
這是推送經(jīng)歷的第二站。出站查票,發(fā)現(xiàn)竟然超員了。
于是乎:我們每天有大量推送因為超過廠商設(shè)定的限額被攔截。
為什么會這樣呢?
實際上:提供推送通道的廠商(沒錯,各手機廠商的自家推送通道良莠不齊),為了保證用戶體驗,會對每個應(yīng)用能夠推送的消息總量進(jìn)行限制。
對于廠商而言,這個限制會根據(jù)推送的類型和應(yīng)用的用戶規(guī)模設(shè)定——推送主要分為產(chǎn)品類的推送和營銷類的推送。
廠商推送通道對于不同類型消息的限制是:
1)對于產(chǎn)品類推送,廠商會保證到達(dá);
2)對于營銷類推送,廠商會進(jìn)行額度限制;
3)未標(biāo)記的推送,默認(rèn)作為營銷類推送對待。
我們剛好沒有對推送進(jìn)行標(biāo)記,因此觸發(fā)了廠商的推送限制。
這對我們的用戶來說,會帶來困擾。閑魚的交易,很依賴買賣家之間的消息互動。這部分消息是需要確保到達(dá)的。
同樣:訂單類的消息、用戶的關(guān)注,也需要保證推送給用戶。
根據(jù)主流廠商的接口協(xié)議,我們將推送的消息分為以下幾類,并進(jìn)行相應(yīng)標(biāo)記:
1)即時通訊消息;
2)訂單狀態(tài)變化;
3)用戶關(guān)注內(nèi)容;
4)營銷消息這幾類。
同時,在業(yè)務(wù)上,我們也進(jìn)行了推送的治理——將用戶關(guān)注度不高的消息,取消推送,避免打擾。
經(jīng)過這些優(yōu)化,因為超過廠商限額而被攔截的推送實現(xiàn)了清零。
8.3 Push點擊率優(yōu)化
通過優(yōu)化agoo受理率、廠商受理率,我們解決了推送到達(dá)量的瓶頸。但即使消息被最終送達(dá),用戶到底點擊了沒有?這才是消息推送的根本意義所在。
于是,在日常的開發(fā)測試過程中,我們發(fā)現(xiàn)了推送的兩個體驗問題:
1)用戶點擊Push有開屏廣告;
2)營銷Push也有權(quán)限校驗,更換用戶登陸后無法點擊。
對于開屏廣告功能,我們增加了Push點擊跳過廣告的能力。
針對Push的權(quán)限校驗功能,閑魚根據(jù)場景做了細(xì)分:
1)涉及個人隱私的推送,保持權(quán)限校驗不變;
2)營銷類的推送,放開權(quán)限校驗。
以上是點擊體驗的優(yōu)化,我們還需要考慮用戶的點擊意愿。
用戶點擊量與推送的曝光量、推送素材的有趣程度相關(guān)。推送的曝光量又和推送的到達(dá)量、推送的到達(dá)時機有關(guān)。
具體的優(yōu)化手段是:
1)在推送內(nèi)容上:我們需要優(yōu)化的是推送的時機和相應(yīng)的素材;
2)在推送時機上:算法會根據(jù)用戶的偏好和個性化行為數(shù)據(jù),計算每個用戶的個性化推送時間,在用戶空閑的時間推送(避免在不合適的時間打擾用戶,同時也能提升用戶看到推送的可能性)。
3)在推送素材上:算法會根據(jù)素材的實時點擊反饋,對素材做實時賽馬。只發(fā)用戶感興趣的素材,提高用戶點擊意愿。
9、實際優(yōu)化效果
通過以上我們的分析和技術(shù)優(yōu)化手段,整體弱推送鏈路鏈路有了不錯的提升,離線消息的到達(dá)率相對提升了兩位數(shù)。
10、寫在最后
本篇主要和大家聊的是只是IM消息系統(tǒng)鏈路中的一環(huán)——弱感知鏈路的優(yōu)化,落地到到具體的業(yè)務(wù)也就是離線消息送達(dá)率問題。
整體IM消息系統(tǒng),還是一個比較復(fù)雜的領(lǐng)域。
我們在消息系統(tǒng)的發(fā)展過程中,面臨著如下問題:
1)如何進(jìn)行消息的鏈路追蹤;
2)如何保證IM消息的快速到達(dá)(見《閑魚億級IM消息系統(tǒng)的及時性優(yōu)化實踐》);
3)如何將消息的玩法和底層能力分離;
4)離線推送中如何通過用戶找到對應(yīng)的設(shè)備。
這些問題,我們在以前的文章中有所分享,以后也會陸續(xù)分享更多,敬請期待。
附錄:相關(guān)資料
[1]?Android P正式版即將到來:后臺應(yīng)用?;?、消息推送的真正噩夢
[2]?一套高可用、易伸縮、高并發(fā)的IM群聊、單聊架構(gòu)方案設(shè)計實踐
[3]?一套億級用戶的IM架構(gòu)技術(shù)干貨(上篇):整體架構(gòu)、服務(wù)拆分等
[4]?一套億級用戶的IM架構(gòu)技術(shù)干貨(下篇):可靠性、有序性、弱網(wǎng)優(yōu)化等
[5]?從新手到專家:如何設(shè)計一套億級消息量的分布式IM系統(tǒng)
[6]?企業(yè)微信的IM架構(gòu)設(shè)計揭秘:消息模型、萬人群、已讀回執(zhí)、消息撤回等
[7]?融云技術(shù)分享:全面揭秘億級IM消息的可靠投遞機制
[8]?移動端IM中大規(guī)模群消息的推送如何保證效率、實時性?
[9]?現(xiàn)代IM系統(tǒng)中聊天消息的同步和存儲方案探討
[10]?新手入門一篇就夠:從零開發(fā)移動端IM
[11]?移動端IM開發(fā)者必讀(一):通俗易懂,理解移動網(wǎng)絡(luò)的“弱”和“慢”
[12]?移動端IM開發(fā)者必讀(二):史上最全移動弱網(wǎng)絡(luò)優(yōu)化方法總結(jié)
[13]?IM消息送達(dá)保證機制實現(xiàn)(一):保證在線實時消息的可靠投遞
[14]?IM消息送達(dá)保證機制實現(xiàn)(二):保證離線消息的可靠投遞
[15]?零基礎(chǔ)IM開發(fā)入門(一):什么是IM系統(tǒng)?
[16]?零基礎(chǔ)IM開發(fā)入門(二):什么是IM系統(tǒng)的實時性?
[17]?零基礎(chǔ)IM開發(fā)入門(三):什么是IM系統(tǒng)的可靠性?
[18]?零基礎(chǔ)IM開發(fā)入門(四):什么是IM系統(tǒng)的消息時序一致性?
本文已同步發(fā)布于“即時通訊技術(shù)圈”公眾號。
同步發(fā)布鏈接是:http://www.52im.net/thread-3748-1-1.html?