文章很長,且持續更新,建議收藏起來,慢慢讀!瘋狂創客圈總目錄 博客園版 爲您奉上珍貴的學習資源 :
免費贈送 :《尼恩Java面試寶典》 持續更新+ 史上最全 + 面試必備 2000頁+ 面試必備 + 大廠必備 +漲薪必備
免費贈送 :《尼恩技術聖經+高併發系列PDF》 ,幫你 實現技術自由,完成職業升級, 薪酬猛漲!加尼恩免費領
免費贈送 經典圖書:《Java高併發核心編程(卷1)加強版》 面試必備 + 大廠必備 +漲薪必備 加尼恩免費領
免費贈送 經典圖書:《Java高併發核心編程(卷2)加強版》 面試必備 + 大廠必備 +漲薪必備 加尼恩免費領
免費贈送 經典圖書:《Java高併發核心編程(卷3)加強版》 面試必備 + 大廠必備 +漲薪必備 加尼恩免費領
免費贈送 資源寶庫: Java 必備 百度網盤資源大合集 價值>10000元 加尼恩領取
億級推送,得物是怎麼架構的?
說在前面
在40歲老架構師 尼恩的讀者交流羣(50+)中,很多小夥伴拿到一線互聯網企業如阿里、網易、有贊、希音、百度、滴滴的面試資格。
最近,尼恩指導一個小夥伴簡歷,需要織入亮點項目、黃金項目。
前段時間,指導小夥寫了一個《高併發消息推送項目》,幫這個小夥拿到 字節/汽車之家 等優質機會,並且幫他 喜提一個 “中間件王子offer” , 尼恩還對此案例進行了全面覆盤:
被裁不慌,9年小夥1個月喜提年薪60W offer,做中間件架構,爽歪了
所以說,《高併發消息推送項目》 是一個牛逼的項目。
爲了幫助大家拿到更多面試機會,拿到更多大廠offer, 在此文之前,尼恩還專門有文章對 消息推送的架構進行介紹:
架構總是無止境的。
前段時間尼恩看到了一個非常優質的案例 《從0到1,億級消息推送的穩定性保障》, 這個案例,是一個非常優質的案例, 也是是一個億級推送的生產案例、工業案例。
尼恩對這個案例進行了深入研讀/二次分析, 吸納到咱們的架構體系裏面來, 爲大家的所用,用於尼恩指導大家做簡歷改造。
也一併把這個案例,收入咱們的 《尼恩Java面試寶典》V169版本《架構專題》,供後面的小夥伴參考,提升大家的 3高 架構、設計、開發水平。
最新《尼恩 架構筆記》《尼恩高併發三部曲》《尼恩Java面試寶典》的PDF,請到公號【技術自由圈】獲取
此文的原創是得物技術的架構師暖樹,並不是尼恩。 但是原文不是太好懂 ,尼恩僅僅以學習筆記的形式, 對原文做二次 學習, 把原因改造得儘量淺顯易懂。
由於無法聯繫到作者本人,尼恩的學習和改造也沒有獲得作者的同意。
特別說明,如果得物技術或者作者暖樹本人不同意 尼恩的學習改造, 可以發消息給尼恩, 立馬就從尼恩的自媒體扯下來。
本文目錄
推送的巨大價值
從用戶的生命週期來看,消息推送對於提高 App 活躍度、提升用戶粘性和用戶留存率都起到了重要作用。
-
提升新用戶次日留存,低成本促活,對平臺的短期留存率影響顯著。
-
提升老用戶活躍度,push 可以通過外部提醒起到拉活的作用。
很多內容平臺類 App 的用戶 push 首次啓動佔比可達 10%以上,因此 push 對 DAU 的增量貢獻不容小覷。
-
流失用戶召回,當用戶流失後,若 push 權限未關閉,通過消息推送的方式,有可能重新喚醒用戶。
消息推送每天都在我們的手機上發生,如圖所示,除非你的手機沒有安裝App或關閉了通知欄權限。
通用推送服務功能分析:
-
發送通知
-
對通知進行優先級排序
-
根據客戶的保存偏好發送通知
-
支持單個/簡單的通知消息和批量通知消息
-
各種通知的分析用例
-
通知消息的報告
一般來說,推送的渠道很多,包括的電子郵件、短信、聊天、釘釘、企業微信和其他公共社交應用:
-
聊天 - 微信Wechat/QQ
-
站內推送通知(移動設備和Web瀏覽器)
-
站外推送通知(移動設備,APP沒有開啓)
-
短信(如登錄密碼、營銷活動)
-
電子郵件
-
釘釘
-
企業微信
通用推送系統設計架構:
注意:請點擊圖像以查看清晰的視圖!
推送非功能性需求(NFR):
-
高性能: qps > 1W
-
高可用性(HA): 99.99%
-
低延遲: TP99 在10ms以下
-
高擴展:可擴展/可插拔的設計,以便添加更多適配器和提供商,與所有通知模塊的API集成以及與客戶端和服務提供商/供應商的外部集成
-
跨平臺:支持Android/iOS移動設備和桌面/筆記本電腦的Web瀏覽器
-
自伸縮:可在本地(VMware Tanzu)和 AWS、GCP 或 Azure 等公共雲服務上擴展負載
推送的SLA 服務等級指標
SLA(Service-Level Agreement),也就是服務等級協議,指的是系統服務提供者(Provider)對客戶(Customer)的一個服務承諾。
SLA(Service-Level Agreement)是衡量一個大型分佈式系統是否“健康”的常見方法。在開發設計系統服務的時候,無論面對的客戶是公司外部的個人、商業用戶,還是公司內的不同業務部門,我們都應該對自己所設計的系統服務有一個定義好的 SLA。
因爲 SLA 是一種服務承諾,所以指標可以多種多樣。下面是四個常見的SLA指標 ,可用性、準確性、系統容量和延遲。
1. 可用性(Availability)
可用性指的是系統服務能正常運行所佔的比例。
例如我們說要搭建一個”100%“的系統服務,也就意味我們要需要保證在任何時候這個系統都能運行,都說可用的,但實際這在現實中,是非常困難的,成本也是非常的高。
對於大部分的系統而言,能保證4個9的可用性(99.99%的可用性)就可以說這個系統是高可用的。
99.99%的可用性是指一天(60×60×24秒),只有8.64秒(60×60×24×0.0001秒)爲不可用,一年就是大概有52.56分鐘(8.64*365/60分鐘)不可用。
99.99% 一天只有8秒左右的不可能用時間,這已經可用滿足大部分系統的要求了。
2. 準確性(Accuracy)
準確性指的是我們所設計的系統服務中,是否允許某些數據是不準確或丟失,如果允許那麼允許的百分比是多少?
不同系統對準確率都會有一個衡量的指標,大部分系統可以 用錯誤率來衡量。
錯誤率怎麼計算呢?可以用導致系統內部錯誤有效請求數除以總的有效請求數而求得。
錯誤率=導致系統內部錯誤有效請求數/總的有效請求數
系統一分鐘內收到的總的有效請求爲100個,其中有10個導致系統內部錯誤,則我們可以認爲錯誤率爲10%
下面我們看下大公司中對系統錯誤率的對比
Google Cloud Platform 的SLA中,有着這樣的定義:
每個月的錯誤率超過5%的時間要少於0.1%,以每分鐘爲單位來計算。
亞馬遜AWS雲計算平臺對SLA的準確性定義爲:
以每5分鐘爲單位,錯誤率不會超過0.1%。
那我們可以通過哪些途徑來獲取系統的準確性呢?大部分情況我們可以通過軟件測試或系統日誌來判斷。
3. 系統容量(Capacity)
在數據處理中,系統容量通常指的是系統能夠支持的預期負載量是多少,一般會以每秒請求數爲單位來表示。
我們常常聽見某個系統的架構可以處理的QPS(Queries Per Second 系統每秒查詢數)是多少或者RPS(Requests Per Second系統每秒請求數)是多少。
4. 延遲(Latency)
延遲指的是系統在收到用戶的請求到響應這個請求的時間間隔。
在定義延遲的SLA時,我們常常看到系統的SLA會有p95或者是p99這樣的延遲聲明。
這裏的p指的是percentile(也就是百分比的意思),假設一個p95的系統延遲是1秒,那就表示100個請求裏面有95個請求的響應時間是少於1秒的,而剩下的5個大於1秒。
對於消息推送而言,我們主要關注的是消息能否及時可靠的送達給用戶,也就是 SLA 中關注的延遲(Latency)、準確性(Accuracy)和可用性(Availability)的問題。
得物推送背景和痛點
消息中心爲得物 App 提供了強大、高效的用戶觸達渠道,推送對於得物 DAU 的貢獻有可觀的佔比,每一條推送消息,這也就意味着都是一次與用戶溝通的寶貴機會。
得物推送背景和痛點:
- 延遲(Latency)
與用戶主動點擊的WEB場景不同,在推送場景,用戶是被動參與的。
業務方對於推送的消息什麼時候到達沒有明確的心理預期。
在這裏,可用性的度量是模糊的。
如何提升推送的低延遲,首先需要我們針對消息推送的鏈路單元耗時進行監控,然後對各個鏈路單元的耗時做針對性的優化,不斷降低延遲。
- 可用性(Availability)
消息推送的穩定性依賴於第三方的推送通道,而三方通道對於我們來講就是個黑盒子。
如何提升推送的可用性(Availability),關鍵是要做到三方通道異常及時發現,並且及時止損,也是需要考慮的問題。
從以上兩個維度來說,都需要對系統進行全面的監控。
得物推送的深度監控實踐
目前消息中心針對實效性和穩定性的開發已經完成並初顯成效,下面主要針對時效性和穩定性的監控做一些介紹。
監控系統架構圖
監控分爲三個維度:
-
第一維度:全鏈路監控
-
第二維度:廠商監控
廠商的監控代碼要從主流程邏輯中解耦,通過旁路流程進行異步的監控。
每天有數億的消息推送,在這種大規模推送背景下,異步的監控,就不會影響主流程的處理性能。
- 第三維度:業務方監控
第一維度:全鏈路監控
1. 鏈路的拆分
首先,需要對全鏈路進行細粒度的拆分。 在拆分之前咱們先從宏觀維度,看看 得物推送後臺的 消息流轉流程,宏觀上包括 下面的四個階段:
- 業務發消息
- 推送預處理編排
- 目標通道接入
- 目標通道完成消息推送
具體如下圖:
如何做到全鏈路時效性的無死角監控?
首先,對消息推送的整個流程進行深入解耦,解耦出若干個獨立的、可監控單元鏈路單元。
整個推送流程,主要會經歷:
-
推送鑑權
-
用戶查詢
-
防疲勞過濾
-
防重複過濾等
這些業務單元,每個單元的邏輯的處理是相互獨立且無依賴的,可以按照單元進行拆分,對每一個單元進行監控。
這樣就可以做到拆分無遺漏,監控無死角,拆分後的具體鏈路單元如下:
2. 鏈路單元耗時的計算
具體的鏈路單元耗時邏輯的計算如下圖:
每一個鏈路單元,都設計多個 核心時間節點,比如 操作開始時間,操作完成時間。
3. 鏈路單元指標的制定
既然需要監控的鏈路單元已經拆分明確了,那針對這些鏈路單元我們監控哪些指標纔是有意義的呢。
目前消息推送高峯耗時較長,業務域對於消息的到達時間也沒有心理預期,所以涉及另個核心指標:
-
鏈路單元的推送耗時
-
鏈路單元的推送量/阻塞量
鏈路單元耗時的計算公式:
這一個操作完成時間 - 上一個操作完成的時間 ,
例如
防疲勞耗時=T7(antiFatigueConsumeTime)-T6(checkrepeatConsumeTime)
鏈路單元阻塞量的計算:
記錄鏈路單元消息推送的瞬時阻塞量,
例如防疲勞鏈路單元阻塞量 =
防疲勞的總量-防疲勞已經處理的量
鏈路單元的阻塞量,是度量是否有積壓的核心指標,如果存在積壓,就需要擴容。
當然,在大促期間,消息的推送量也會達到一個高峯,往往都存在積壓問題,需要進行提前擴容。
考慮到消息推送是有優先級的並且區分單推和批量推,所以我們要針對不同的優先級和推送方式設置不同的標準,消息推送耗時的具體標準如下。
4. 全鏈路技術方案的實現
首先,要考慮高併發、高吞吐場景。
消息中心每天推送大量消息給得物用戶,SLA 全鏈路監控,一定不嵌入主流程, 任何一個操作嵌入主流程中都可能導致消息推送的延遲。
這也就要求監控和主流程進行隔離,主流程的歸主流程,SLA 的歸 SLA。
SLA 監控代碼從主流程邏輯中剝離出來,徹底避免 SLA 代碼對主流程代碼的污染。
SLA 邏輯技術方案的實現的要求:
-
獨立於推送業務的主流程進行異步計算,防止 SLA 監控拖垮整個主流程
-
使用非入侵的方式,我們使用的是 Spring AOP註解的方式
SLA 邏輯技術方案的 技術方案:Spring AOP+Spring Event。
主要鏈路單元包括鑑權、風控、用戶查詢、防疲勞、防重複、廠商調用,通過鏈路單元拆分,一單出現指標異常,可以很快定位到異常發生的具體位置。
5. 全鏈路監控結果
時效性鏈路單元監控:
時效性鏈路單元告警:
消息推送實效性監控做完之後,實現了 指標化和預警化:
-
指標化:關鍵鏈路單元耗時的指標化,
-
預警化:對服務鏈路單元耗時異常可以及時感知,同時也完成了預警的對接
第二維度: 廠商推送監控
1. 監控指標制定
對 廠商推送監控, 主要涉及到三個核心指標:
- 推送成功率
- 回執成功率
- 點擊率
如果出現推送成功率跌零、回執成功率跌零、點擊率的跌零, 就需要進行技術的預警,這種情況下整個推送通道都掛掉了,我們要及時通知廠商進行修復,
另外,如果沒有跌零,是不是也要監控呢? 是的。
一般來說,廠商的推送成功率、回執成功率、點擊率都穩定在一定的的區間。如果廠商推送的指標數據偏離這個區間則說明推送有異常,也要進行告警和排查。
廠商監控監控告警的維度大致如下:
對這些指標,可以通過 Prometheus+grafana指標平臺,進行時序展示:
2. 廠商推送監控技術方案實現
在落地面,監控技術方案首先不能影響主流程中處理,
因爲每天有數億的消息推送,如果影響到核心流程,那麼核心流程性能會大大降低。
所以,和第一個維度鏈路的監控類似,廠商的監控代碼要從主流程邏輯中剝離出來,避免監控拖垮主流程,同樣避免監控異常影響到推送的主流程。
如何解耦呢?這裏使用的是有界內存隊列實現。
3. 結果
消息推送廠商監控上線之後,可以及時感知到廠商推送的異常信息,對於廠商推送的異常和廠商規則的更改等可以做到及時的感知。
第三維度:業務方監控
這裏涉及到業務方的調用速率、消息的發送數量(單條和批量發生)、成功比例進行監控和預警。
這裏得物原文沒有給出方案, 應該是有遺漏了。
得物推送監控帶來的收益
1. 及時發現線上異常
監控上線後,能及時發現廠商的很多線上以上:
- 推送線程關閉失敗
- 廠商推送跌零
- 廠商營銷消息規則更改
- 廠商通道偶發不可用
- 等問題
及時發現異常後,就可以做到了及時的止損。
- 在時效性監控上線之後,發現了因廠商推送線程創建關閉失敗導致線程數逐漸上升問題,避免了線上故障的發生。
- 廠商異常導致推送跌零,監控發現後及時通知到廠商並止損。
- 發現廠商營銷消息規則更改的異常,
並及時經梳理各大廠商文檔後,發現除了多個廠商通道在未來一個月內也會有規則的更改,消息平臺團隊對規則進行優化及時適應了廠商規則,接入廠商系統通道,做到了及時止損。
2. 幫助連接池和連接時間參數優化
通過全鏈路的有效性監控,發現了多個服務可以優化的點,
比如,發現多個廠商和推送鏈路單元在高峯推送時耗時較高,發現廠商推送 SDK 連接池和連接時間參數需要優化, 優化後消息推送整體的吞吐量實現了翻倍的提升。
得物推送監控總結
得物推送監控上線後,帶來的收益還是比較可觀的,
展望未來,後續可以從以下點豐富現有監控。
-
後續將針對各個鏈路單元的推送異常、漏斗轉化率、服務性能等做監控,進一步豐富消息平臺的監控體系。
-
後續將對推送的轉化率問題進行監控
-
後續將對卸載、屏蔽等指標也是我們需要監控的點,
總之,通過對業務指標進行擴展,及時感知推送的效果,做到精細化的管控。
說在最後:有問題找老架構取經
推送系統,是一個很黃金的系統。
如果寫入簡歷,並且面試的時候能對答如流,如數家珍, 面試官會被你 震驚到、吸引到。
最終,讓面試官愛到 “不能自已、口水直流”。
offer, 也就來了。
在面試之前,建議大家系統化的刷一波5000頁《尼恩Java面試寶典PDF》 ,裏邊有大量的大廠真題、面試難題、架構難題。很多小夥伴刷完後, 吊打面試官, 大廠橫着走。
在刷題過程中,如果有啥問題,大家可以來 找 40歲老架構師尼恩交流。
金三銀四挪窩的黃金時期到了,建議大家簡歷上織入一個 《推送系統》, 當然如果不知道怎麼織入,可以找尼恩來改簡歷、做幫扶。
遇到職業難題,找老架構取經, 可以省去太多的折騰,省去太多的彎路。尼恩指導了大量的小夥伴上岸,前段時間,剛指導一個40歲+被裁小夥伴,拿到了一個年薪100W的offer。
狠狠卷,實現 “offer自由” 很容易的, 前段時間一個武漢的跟着尼恩捲了2年的小夥伴, 在極度嚴寒/痛苦被裁的環境下, offer拿到手軟, 實現真正的 “offer自由” 。
技術自由的實現路徑:
實現你的 架構自由:
《阿里二面:千萬級、億級數據,如何性能優化? 教科書級 答案來了》
《峯值21WQps、億級DAU,小遊戲《羊了個羊》是怎麼架構的?》
… 更多架構文章,正在添加中
實現你的 響應式 自由:
這是老版本 《Flux、Mono、Reactor 實戰(史上最全)》
實現你的 spring cloud 自由:
《Spring cloud Alibaba 學習聖經》 PDF
《分庫分表 Sharding-JDBC 底層原理、核心實戰(史上最全)》
《一文搞定:SpringBoot、SLF4j、Log4j、Logback、Netty之間混亂關係(史上最全)》
實現你的 linux 自由:
實現你的 網絡 自由:
《網絡三張表:ARP表, MAC表, 路由表,實現你的網絡自由!!》
實現你的 分佈式鎖 自由:
實現你的 王者組件 自由:
《隊列之王: Disruptor 原理、架構、源碼 一文穿透》
《緩存之王:Caffeine 源碼、架構、原理(史上最全,10W字 超級長文)》
《Java Agent 探針、字節碼增強 ByteBuddy(史上最全)》