本文由轉(zhuǎn)轉(zhuǎn)平臺(tái)業(yè)務(wù)負(fù)責(zé)人王計(jì)寬分享,原題“轉(zhuǎn)轉(zhuǎn)push系統(tǒng)的演進(jìn)之路”,下文有修訂和重新排版。
1、引言
顧名思義,push就是就是借助廠商通道把消息發(fā)送給用戶的一種方式,一般用于用戶的召回和活動(dòng)觸達(dá),和即時(shí)通訊IM在業(yè)務(wù)上稍有區(qū)別,但技術(shù)邏輯上是相通的,不在此處贅述。
本文將從0開始講講轉(zhuǎn)轉(zhuǎn)千萬級(jí)用戶量消息推送系統(tǒng)的架構(gòu)演進(jìn)和迭代過程,以及遇到的常見問題的解法,希望能帶給你啟發(fā)。

2、術(shù)語解釋
以下是本文涉及到的一些技術(shù)術(shù)語的解釋:
1)業(yè)務(wù)屬性:運(yùn)營(yíng)、業(yè)務(wù)、功能類推送;
2)推送范圍: 月活、全量、定向推送、個(gè)性化推送;
3)目標(biāo)端:一般是安卓、ios客戶端;
4)通道:小米、華為、魅族、apns等手機(jī)廠商的常駐連接;
5)token: 用于設(shè)備的唯一標(biāo)識(shí),由APP本身生成;
6)devicetoken:用于推送的唯一標(biāo)識(shí),一般由廠商提供;
7)推送量:推送消息的數(shù)量;
8)到達(dá)率:消息到達(dá)手機(jī)的數(shù)量/推送量;
9)點(diǎn)擊率:用戶點(diǎn)擊量/推送量。
3、當(dāng)前架構(gòu)概覽

現(xiàn)有的架構(gòu)支持后臺(tái)推送、業(yè)務(wù)推送以及個(gè)性化推薦推送。
以下是相關(guān)推送業(yè)務(wù)的特點(diǎn):
1)后臺(tái)推送:一般會(huì)有標(biāo)準(zhǔn)的格式,特點(diǎn)是時(shí)間短、推送量大,比如8點(diǎn)秒殺活動(dòng);
2)業(yè)務(wù)推送 :一般都是業(yè)務(wù)觸發(fā),特點(diǎn)是實(shí)時(shí)性強(qiáng)、優(yōu)先級(jí)高,如訂單支付消息;
3)個(gè)性化推送:經(jīng)常會(huì)和用戶畫像相關(guān),特點(diǎn)是策略復(fù)雜、內(nèi)容多樣,需要有風(fēng)控管理,如猜你喜歡等推薦策略。
4、技術(shù)背景——PM想推送運(yùn)營(yíng)活動(dòng)
步驟:
1)PM從大數(shù)據(jù)平臺(tái)上導(dǎo)出一部分用戶集合;
2)RD寫程序調(diào)用push接口。
問題:
1)N個(gè)PM都有需求,RD..........;
2)8點(diǎn)有一個(gè)突發(fā)情況,9點(diǎn)來一波;
3)每周末都要活動(dòng),推送。
解決方案:
1)搭建一個(gè)后臺(tái),支持根據(jù)用戶ID上傳,解放開發(fā)資源;
2)支持按照時(shí)間推送,支持文案可配;
3)支持安卓、IOS分端推送。
遺留的問題:PM上傳了一個(gè)瀏覽過手機(jī)類目用戶的數(shù)據(jù)集合,數(shù)據(jù)量太大,上傳超時(shí)。PS:用戶量大概在1000w左右+,大約300M左右的文件。
提示:
1)上傳的時(shí)間大約在1分鐘左右, 需要聯(lián)系運(yùn)維設(shè)置最長(zhǎng)的鏈接時(shí)間,否則nginx會(huì)主動(dòng)斷開;
2)上傳由同步上傳,改成進(jìn)度條的方式,讓上傳者可以看到進(jìn)度;
3)上傳和數(shù)據(jù)處理分開(我們當(dāng)時(shí)是邊上傳,邊解析文件比較慢)。
5、希望重大節(jié)日能夠即時(shí)通知到活躍用戶
5.1 實(shí)時(shí)推
問題描述:重大節(jié)日,推送全量用戶、月活、周活數(shù)據(jù),每次僅是文案不同,PM都需要跑大數(shù)據(jù)系統(tǒng),效率太低,當(dāng)天數(shù)據(jù)不可獲得,平均推送需要1個(gè)多小時(shí)。
要求:
1)1億的數(shù)據(jù)能夠在一小時(shí)內(nèi)推送完畢;
2)要覆蓋到某一個(gè)周期內(nèi)的用戶(比如一個(gè)月);
3)支持預(yù)覽,支持暫停。
分析-數(shù)據(jù)量(以2000w月活為例):
1)?全量用戶認(rèn)定為近3個(gè)月(90天)內(nèi)訪問過轉(zhuǎn)轉(zhuǎn)的用戶;
2)?預(yù)估所有設(shè)備數(shù)量在5000w左右;
3)?預(yù)計(jì)占用的空間為5G。
分析-性能(以2000w月活為例):
1)?老系統(tǒng)push的平均QPS是2000;
2)?2000W/2000/60/2=83~=1小時(shí)20分鐘,希望能夠在12分鐘內(nèi)推送完畢(一個(gè)小時(shí)推送1億的指標(biāo))。
難點(diǎn)分析:
1)?數(shù)據(jù)做到準(zhǔn)實(shí)時(shí),怎么算準(zhǔn)實(shí)時(shí);
2)2000千萬的數(shù)據(jù)12分鐘內(nèi)推送完畢,QPS~=2.7w, 如何讓性能提升13.5倍(2k提升到2.7w的并發(fā))。
解決方案:
1)?數(shù)據(jù)的準(zhǔn)實(shí)時(shí):實(shí)時(shí)接收kafka日志消息,每分鐘把清洗的數(shù)據(jù)進(jìn)行合并;
2)需要存儲(chǔ)的數(shù)據(jù)要素:用戶的token信息(注意不是devicetoken);此token的活躍時(shí)間(時(shí)間戳);
3)用戶數(shù)據(jù)存儲(chǔ)選型。

最終選擇redis的zset進(jìn)行存儲(chǔ)。
5.2 如何提高發(fā)送性能
首先分析之前之所以慢的原因:
1)?單線程發(fā)送;
2)?受到廠商通道的限制,單接口耗時(shí)100ms+(IOS通道)。
解決方案:
1)區(qū)分安卓、IOS單獨(dú)發(fā)送,原始程序只負(fù)責(zé)從redis拿到數(shù)據(jù)后拼裝成固定結(jié)構(gòu)(簡(jiǎn)單拼接操作速度很快);
2)把數(shù)據(jù)推送到MQ中(可以不用MQ嗎?);
3)多個(gè)消費(fèi)訂閱者,進(jìn)行消費(fèi)(容易擴(kuò)展),通過廠商 通道推送出去。
注意:iOS通道,我們用的pushy開源工具,特定情況下無法持續(xù)推送消息,需要定時(shí)檢查,重新創(chuàng)建通道。
最后的效果:push推送的QPS達(dá)到3w+,推送能力提升的同時(shí),也引發(fā)了以下問題。
5.3 業(yè)務(wù)服務(wù)器扛不住瞬時(shí)流量
問題描述:當(dāng)push的推送能力上去了之后, 用戶的瞬時(shí)訪問問題隨之而來
1)瞬時(shí)的流量高峰,導(dǎo)致超時(shí)增多;
2)部分請(qǐng)求到達(dá)性能瓶頸,超時(shí)增多,頁面打不開~,見下圖。
push落地效果:

解決辦法:
1)最簡(jiǎn)單的辦法:加機(jī)器;
2)業(yè)務(wù)接口多線程、服務(wù)治理,消峰(ratelimit);
3)app核心功能增加緩存,保證不會(huì)出現(xiàn)白屏的情況;
4)減少活動(dòng)路徑。(一般push都會(huì)落地到某一個(gè)活動(dòng)頁面。但是正常打開push,都會(huì)先進(jìn)入首頁,在跳轉(zhuǎn)到活動(dòng)頁面。給push的消息增加特殊埋點(diǎn),如果是此類push消息,就直接 跳轉(zhuǎn)到特定頁面,減少中間環(huán)節(jié)。)
6、AB實(shí)驗(yàn)室
問題描述:有一天晚上9點(diǎn)推送了一個(gè)運(yùn)營(yíng)類的push,發(fā)現(xiàn)居然點(diǎn)擊率超級(jí)高,是文案優(yōu)秀?還是流量高峰?
要求:存在多個(gè)推送文案,系統(tǒng)能夠擇優(yōu)選擇點(diǎn)擊率最好的進(jìn)行推送?
解決方式:加入AB測(cè)的能力,先進(jìn)行少量用戶推送,根據(jù)AB的效果,擇優(yōu)推送.
7、整合全部手機(jī)廠商級(jí)ROOM推送通道
新的問題:之前安卓的通道我們僅有小米通道+個(gè)推(個(gè)推達(dá)到率一般,做托底), 如果我們向華為手機(jī)推送消息,也是通過小米通道是很難到達(dá)的。
要求:
1)希望能夠把大廠的廠商通道都接進(jìn)來;
2)推送的消息能夠根據(jù)用戶最后登錄的通道進(jìn)行優(yōu)化推送;
3)速度不能慢下來。
解決方式:
1)?搭建tokens服務(wù),能夠批量判定devicetoken的最后使用的廠商(需要依賴轉(zhuǎn)轉(zhuǎn)客戶端上報(bào));
2)?分庫分表的方式進(jìn)行存儲(chǔ);
3)?數(shù)據(jù)熱備到緩存中。
效果:當(dāng)年統(tǒng)計(jì)能夠提高10%的達(dá)到率。
8、消息送達(dá)監(jiān)控
一般的監(jiān)控維度包含:
1)產(chǎn)品線:轉(zhuǎn)轉(zhuǎn)、找靚機(jī)等等;
2)客戶端:安卓、IOS;
3)指標(biāo):發(fā)送、到達(dá)、點(diǎn)擊的數(shù)量和比例;
4)數(shù)據(jù)對(duì)比:模板、周期;
5)通道:小米、華為、vivo、apns。

9、 本文小結(jié)
現(xiàn)狀:
1)?推送月活10分鐘;
2)?支持暫停、預(yù)覽,實(shí)時(shí)查看推送數(shù)據(jù)量;
3)?支持提前AB看效果;
4)?支持不在線,微信通知;
5)?支持防打擾;
6)?支持優(yōu)先級(jí)和廠商高優(yōu)通道。
提高速度:預(yù)加載+緩存+多線程+合理的數(shù)據(jù)結(jié)構(gòu)+批量處理+合理布局+特殊埋點(diǎn)。
折中方案:異步上傳、限流控制、降級(jí)處理、分層解耦、補(bǔ)償通知。
10、 參考資料
[1]?極光推送系統(tǒng)大規(guī)模高并發(fā)架構(gòu)的技術(shù)實(shí)踐分享
[2]?魅族2500萬長(zhǎng)連接的實(shí)時(shí)消息推送架構(gòu)的技術(shù)實(shí)踐分享
[3]?專訪魅族架構(gòu)師:海量長(zhǎng)連接的實(shí)時(shí)消息推送系統(tǒng)的心得體會(huì)
[4]?基于WebSocket實(shí)現(xiàn)Hybrid移動(dòng)應(yīng)用的消息推送實(shí)踐(含代碼示例)
[5]?一個(gè)基于長(zhǎng)連接的安全可擴(kuò)展的訂閱/推送服務(wù)實(shí)現(xiàn)思路
[6]?實(shí)踐分享:如何構(gòu)建一套高可用的移動(dòng)端消息推送系統(tǒng)?
[7]?Go語言構(gòu)建千萬級(jí)在線的高并發(fā)消息推送系統(tǒng)實(shí)踐(來自360公司)
[8]?騰訊信鴿技術(shù)分享:百億級(jí)實(shí)時(shí)消息推送的實(shí)戰(zhàn)經(jīng)驗(yàn)
[9]?京東京麥商家開放平臺(tái)的消息推送架構(gòu)演進(jìn)之路
[10]?技術(shù)干貨:從零開始,教你設(shè)計(jì)一個(gè)百萬級(jí)的消息推送系統(tǒng)
[11]?愛奇藝WebSocket實(shí)時(shí)推送網(wǎng)關(guān)技術(shù)實(shí)踐
[12]?喜馬拉雅億級(jí)用戶量的離線消息推送系統(tǒng)架構(gòu)設(shè)計(jì)實(shí)踐
[13]?消息推送技術(shù)干貨:美團(tuán)實(shí)時(shí)消息推送服務(wù)的技術(shù)演進(jìn)之路
[14]?揭秘vivo百億級(jí)廠商消息推送平臺(tái)的高可用技術(shù)實(shí)踐
[15]?得物從零構(gòu)建億級(jí)消息推送系統(tǒng)的送達(dá)穩(wěn)定性監(jiān)控體系技術(shù)實(shí)踐
[16]?B站千萬級(jí)長(zhǎng)連接實(shí)時(shí)消息系統(tǒng)的架構(gòu)設(shè)計(jì)與實(shí)踐