本文由得物技術暖樹分享,有修訂和改動。
1、引言
本文分享的是得物針對現有的消息推送系統的消息送達耗時、實時性、穩定性等方面問題,從零到一構建完整的消息推送質量監控體系和機制的技術實踐。

- 移動端IM開發入門文章:《新手入門一篇就夠:從零開發移動端IM》
- 開源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK(備用地址點此)
(本文已同步發布于:http://www.52im.net/thread-4614-1-1.html)
2、消息推送的作用
2.1 什么是消息推送
消息推送每天都在我們的手機上發生,如下圖所示,除非你的手機沒有安裝App或關閉了通知欄權限。

2.2 消息推送的價值
從用戶的生命周期來看,消息推送對于提高App活躍度、提升用戶粘性和用戶留存率都起到了重要作用。
比如:
- 1)提升新用戶次日留存,低成本促活,對平臺的短期留存率影響顯著;
- 2)提升老用戶活躍度,push可以通過外部提醒起到拉活的作用;
- 3)流失用戶召回,當用戶流失后,若push權限未關閉,通過消息推送的方式,有可能重新喚醒用戶。
對于第 2)點,很多內容平臺類App的用戶push首次啟動占比可達 10%以上,因此push對DAU的增量貢獻不容小覷。
3、業務背景和技術痛點
消息中心為得物App提供了強大,高效的用戶觸達渠道。其中push對于得物DAU的貢獻有可觀的占比,這也就意味著每一條推送消息都是一次與用戶溝通的寶貴機會。所以推送的穩定性成為我們關注的首要問題。
那么我們遇到的以下痛點就亟待解決:
1)消息中心沒有明確消息推送的耗時標準,業務和技術之間存在gap,業務方對于推送的消息什么時候到達沒有明確的心理預期。
2)從技術上來講消息推送各個節點的耗時不明確,無法對各個節點的耗時做針對性的優化,這也就需要我們針對消息推送的節點耗時進行監控。
3)消息推送的穩定性依賴于第三方的推送通道,而三方通道對于我們來講就是個黑盒子,如何做到三方通道異常及時發現并止損也是需要考慮的問題。
4)在我們正常的迭代過程中有時候不可避免的會出現些異常或者有壞味道的代碼,這些問題能不能及時發現、及時止損,能不能及時告警出來。
4、穩定性監控體系
SLA(Service-Level Agreement),也就是服務等級協議,指的是系統服務提供者(Provider)對客戶(Customer)的一個服務承諾。這是衡量一個大型分布式系統是否“健康”的常見方法。
在開發設計系統服務的時候,無論面對的客戶是公司外部的個人、商業用戶,還是公司內的不同業務部門,我們都應該對自己所設計的系統服務有一個定義好的SLA。因為SLA是一種服務承諾,所以指標可以多種多樣。
最常見的四個SLA指標:
- 1)可用性;
- 2)準確性;
- 3)系統容量;
- 4)延遲。

對于消息推送而言,我們主要關注的是消息能否及時可靠的送達給用戶,也就是SLA中關注的時效性和穩定性的問題。
目前消息中心針對實效性和穩定性的開發已經完成并初顯成效。
系統架構圖:

下面主要針對時效性和穩定性的監控做一些介紹。
5、時效性監控的技術實現
5.1 節點的拆分

如何做到時效性的無死角監控,那么我們就要對消息推送的整個流程進行拆分,把整個流程拆分成若干個獨立且無依賴的可監控節點。
從消息系統流轉圖中可以看到:整個推送流程是清晰明了的,消息的的推送主要會經歷推送鑒權、用戶查詢、防疲勞過濾、防重復過濾等的邏輯處理,考慮到每個業務邏輯的處理是相互獨立且無依賴的,那我們就可以根據具體的業務處理邏輯進行節點的拆分,這樣就可以做到拆分無遺漏,監控無死角。
拆分后的具體節點如下:

5.2 節點耗時的計算
具體的節點拆分邏輯和耗時邏輯的計算如下圖:

節點耗時的計算:記錄節點消息推送到達的時間,并計算節點推送耗時,例如:防疲勞耗時 = T7(antiFatigueConsumeTime) - T6(checkrepeatConsumeTime)。
節點阻塞量的計算:記錄節點消息推送的瞬時阻塞量, 例如:防疲勞節點阻塞量 = 防疲勞的總量 - 防疲勞已經處理的量。
5.3 節點指標的制定
既然需要監控的節點已經拆分明確了,那針對這些節點我們監控哪些指標才是有意義的呢。
1)目前消息推送高峰耗時較長,各業務域對于消息的到達時間也沒有明確的心理一個預期,另外消息中心也無法感知推送在整個鏈路各個節點的耗時情況,無法針對節點耗時做到有針對性的優化,所以節點的推送量和推送耗時就是我們需要重點關注的指標。
2)節點的阻塞量可以讓我們及時感知到推送中存在的積壓問題,在大促期間,消息的推送量也會達到一個高峰,消息目前是否有堆積,處理的速度是否跟的上,是否需要臨時擴容,那么節點的阻塞量就成了一個比較有意義的參考指標。
考慮到消息推送是有優先級的并且區分單推和批量推,所以我們要針對不同的優先級和推送方式設置不同的標準。
消息推送耗時的具體標準如下:

5.4 技術方案的實現
為了能感知到消息推送中發生的異常和耗時情況,這就需要我們標準化監控指標和監控的節點。
其中耗時指標可以感知節點的耗時和代碼的壞味道,阻塞量可以監控到節點的堆積情況,推送成功率可以感知節點的推送異常等。
另外節點拆分后我們可以很快定位到異常發生的具體位置,經過拆分監控的主要節點包括鑒權、風控、用戶查詢、防疲勞、防重復、廠商調用等。
另外消息中心每天推送大量消息給得物用戶,SLA監控任何一個操作嵌入主流程中都可能導致消息推送的延遲。這也就要求監控和主流程進行隔離,主流程的歸主流程,SLA 的歸 SLA,SLA 監控代碼從主流程邏輯中剝離出來,徹底避免SLA代碼對主流程代碼的污染,這也就要求SLA邏輯計算需要獨立于推送業務的主流程進行異步計算,防止SLA監控拖垮整個主流程,那么Spring AOP+Spring Event就是最好的實現方式 。
5.5 成果
消息推送實效性監控做完之后,對服務節點耗時異常可以及時感知,同時也完成了關鍵節點耗時的指標化。
可以明確的看到所有節點在各個時間的耗時情況,同時也對消息推送針對各個節點的的優化起到了指導作用。
時效性節點監控:

時效性節點告警:

6、廠商推送監控的技術實現
6.1 監控指標制定
消息推送接入的有多個推送通道,如何做到對這些通道做到無死角的監控,及時感知呢。
1)在做廠商監控之前,我們就已經遇到了廠商通道推送跌零的情況,這種情況下整個推送通道都掛掉了,我們要及時通知廠商進行修復,所以廠商推送跌零告警和廠商余量監控是必須的。
2)從現有數據來看,廠商的推送成功率、回執成功率、點擊率都穩定在一定的的區間。如果廠商推送的指標數據偏離這個區間則說明推送有異常,所以推送成功率、回執成功率、點擊率的監控是必須的。
3)另外從業務請求發送的用戶數來看,每天的消息推送基本是穩定的,相對應的廠商的回執數量和點擊數量也是穩定的,那么對廠商推送成功的數量,回執的數量和點擊的數量監控也有一定的參考意義。
業務側請求發送的用戶數:

廠商監控告警:

6.2 技術方案實現
廠商每天有數億的消息推送,這也就意味著廠商的監控不能嵌在主流程中處理。廠商的監控代碼要從主流程邏輯中剝離出來,避免監控拖垮主流程,同樣避免監控異常影響到推送的主流程。
針對廠商推送的監控,目前使用的是有界內存隊列實現:

6.3 成果
消息推送廠商監控上線之后,可以及時感知到廠商推送的異常信息,對于廠商推送的異常和廠商規則的更改等可以做到及時的感知。


7、 穩定性監控體系帶來的收益
7.1 異常的及時發現
監控上線后及時發現了發現了廠商推送線程關閉失敗,廠商推送跌零、廠商營銷消息規則更改、廠商通道偶發不可用等問題,并做到了及時的止損。
1)在時效性監控上線之后,發現了因廠商推送線程創建關閉失敗導致線程數逐漸上升問題,避免了線上故障的發生。

2)廠商異常導致推送跌零,監控發現后及時通知到廠商并止損。

3)發現廠商營銷消息規則更改的異常,并及時經梳理各大廠商文檔后發現除了多個廠商通道在未來一個月內也會有規則的更改,消息平臺及時適應了廠商規則,接入廠商系統通道,做到了及時止損。

7.2 服務性能的提升
時效性監控上線后發現了多個服務可以優化的點,其中多個廠商和推送節點在高峰推送時耗時較高,很明顯節點耗時和廠商推送 SDK 連接池和連接時間參數需要優化。優化后消息推送整體的吞吐量實現了翻倍的提升。
8、 展望未來
由于時間問題,目前消息監控只做了時效性和廠商推送穩定性相關的監控,但是監控上線后帶來的收益還是比較可觀的,可以預見的是監控的構建在未來必將帶給我們更大的收益,后續我們可以從以下點豐富現有監控。
1)考慮到業務預的推送量和推送時間是穩定的,那么我們可以針對業務維度添加推送數據的監控,及時感知上游推送數據的變化。
2)其次我們可以針對各個節點的推送異常、漏斗轉化率、服務性能等做監控,進一步豐富消息平臺的監控體系。
3)對于消息推送來講也要考慮推送的轉化率問題,那么卸載、屏蔽等指標也是我們需要監控的點,通過這些業務指標及時感知推送的效果,做到精細化的管控。
9、本文小結
消息平臺監控上線后帶來的收益還是比較可觀的,包括多次異常的及時發現和止損,還有發現多個個可以優化的性能點,實現了服務高峰吞吐量的翻倍。
同時也解決了我們現在遇到的以下痛點:
1)時效性明確的給到了不同優先級的耗時標準,避免了業務和技術之間的gap,業務方對于推送的耗時也有了明確的心理預期。
2)時效性使得節點耗時的性能問題可以一目了然,通過對現有節點耗時問題的優化,消息服務的吞吐量實現了翻倍的提升。
3)廠商穩定性監控使得廠商異常可以及時感知,其中廠商穩定性監控上線后發現多起廠商推送的異常,并做到了及時的解決和止損。
4)SLA時效性和廠商穩定性上線后,消息中心可以及時感覺到推送鏈路的異常和代碼的壞味道,特別是對于新上線的代碼,如果存在異常可以及時感知。
10、相關文章
[2] 魅族2500萬長連接的實時消息推送架構的技術實踐分享
[3] 專訪魅族架構師:海量長連接的實時消息推送系統的心得體會
[5] Go語言構建千萬級在線的高并發消息推送系統實踐(來自360公司)
[9] 技術干貨:從零開始,教你設計一個百萬級的消息推送系統
[10] 長連接網關技術專題(四):愛奇藝WebSocket實時推送網關技術實踐
[12] 直播系統聊天技術(三):微信直播聊天室單房間1500萬在線的消息架構演進之路
[13] 消息推送技術干貨:美團實時消息推送服務的技術演進之路
[14] 揭秘vivo百億級廠商消息推送平臺的高可用技術實踐
11、 得物分享的其它文章
《IM跨平臺技術學習(七):得物基于Electron開發客服IM桌面端的技術實踐》
(本文已同步發布于:http://www.52im.net/thread-4614-1-1.html)
作者:Jack Jiang (點擊作者姓名進入Github)
出處:http://www.52im.net/space-uid-1.html
交流:歡迎加入即時通訊開發交流群 215891622
討論:http://www.52im.net/
Jack Jiang同時是【原創Java
Swing外觀工程BeautyEye】和【輕量級移動端即時通訊框架MobileIMSDK】的作者,可前往下載交流。
本博文
歡迎轉載,轉載請注明出處(也可前往 我的52im.net 找到我)。