app用戶全局消息推送框架方法

需求描述

爲何要儘快到達用戶端呢?ios

由於消息具備時效性,在一個不恰當的時間給用戶消息,不只容易被忽略,並且會騷擾到用戶。mongodb

咱們須要解決幾個問題:json

一、用戶按活躍日期由新到舊順序排序。緩存

二、推送過程當中途中止後,能夠從新推送新消息。那麼就須要一個能夠重複消費的高性能消息隊列。服務器

三、消息推送過程,用戶可能網絡在那時間點沒鏈接上,因此須要存儲起來,等用戶鏈接上來的時候同步消息。因而,須要一個高性能的存儲。網絡

四、用戶能夠按條件篩選出指定的一部分用戶。(男/女)(主播/用戶)(商家/用戶)架構

存量用戶量級,咱們以5000W作爲目標。性能

如下爲架構圖:spa

用戶活躍排序

首先,從點擊「消息推送」按鈕開始,須要儘快發送用戶。因而,用戶活躍排序不能是臨時排序,必須提早排好序。咱們採用天天凌晨4點,導出一份用戶活躍排序的數據。.net

其次,活躍用戶有必定量級,會產生大量的網絡鏈接/斷開鏈接(長鏈接架構)。若是是短鏈接架構可能會更多。每次用戶鏈接活躍就會記錄下這個用戶的活躍時間點,那麼也須要一個高寫入性能可擴展的存儲。

最後,排序導出的用戶活躍的過程,不能產生重複的用戶數據(快照),不然就會有用戶重複收到相同的消息。

這裏採用了mongodb的wiredtiger引擎來處理記錄用戶的活躍時間以及ios token等信息。高寫入性能,而且能夠支持按任意索引來排序導出快照。這裏存儲的用戶信息,除了提供給推送系統外,還會提供給其它系統使用。例如用來查詢userID與DeviceID之間的關係。

(mongodb分片按照用戶來區分)

導出了用戶活躍數據,就能夠把這個預先插入到消息隊列裏,等待隨時被消費。

 

消息隊列

消息可隨時終止推送,而且從新發送新消息。那麼就要求消息隊列裏的用戶數據在消費後不能立刻就刪除了,要可重用。

這裏採用Kafka做爲消息隊列,消息消費至關於遊標移動。當須要終止推送時,遊標從新迴歸初始值便可從新消費。不存在從新導出用戶活躍排序和從新加載進隊列的過程。

消息存儲

消息的特性是:

一、有時效性,因此須要有數據過時功能。

二、數據量很大,高寫入,高刪除,無更新。須要儘可能避免磁盤碎片。

三、基本都是冷數據,消息讀取一次,就不會再讀了。緩存無做用。

採用cassandra的一大緣由:

一、相比mongodb節約資源。cassandra採用DateTieredCompactionStrategy存儲策略,很是適合臨時性數據的刪除和回收。避免壓縮數據時,還須要預留一倍的內存來作壓縮操做。

二、架構相對mongodb層級要少,性能消耗更少,更容易管理。

(cassandra分片按照用戶來區分)

消息的重要性:

一、不只僅應用於消息推送,用戶之間的IM私信、訂閱的內容提醒等等。因此必需要可容災的。

二、當推送的速度很快,佔滿了消息存儲的資源怎麼辦?這是須要推送服務控制好速度的。

 

按條件篩選出用戶

這種狀況若是要作出一個理想的方法比較難。咱們假設分爲兩種狀況:

一、條件比較少,篩選出來的用戶比較多。(商家/用戶)

二、條件比較多,篩選出來的用戶比較少。(廣州天河區的男性用戶)

第一種狀況,咱們依舊採起預處理的方法。與全局用戶的處理方法同樣,只是分了不一樣的隊列名。

第二種狀況,因爲數據量比較少了。咱們能夠動態篩選用戶,這須要耗費必定時間在篩選用戶上面,不能當即推送。但因爲用戶量少了,最終的完成時間也會在可控範圍內。

回顧

從效果上看,當運營操做人員點擊「推送消息」按鈕開始,最近活躍用戶就馬上陸續收到了消息推送。每一個環節都是可擴展的,以普通服務器爲評估,Kafka消費每秒6W+不成問題,cassandra寫入每秒4W+,推送服務每秒2W+(json解析格式比較耗時)(部署兩個實例)。比較容易就達到了4~5W的速度。1分鐘300W用戶;5000W用戶大約16分鐘能夠處理完成。固然,這是把資源耗光的計算方法了,實際上仍是須要預留資源的,並且也會擴展多個節點來擴展性能。

 

原創博客,轉帖請註明原出處:http://my.oschina.net/u/223522/blog/726417

相關文章
相關標籤/搜索