編者按:本文來自微信公眾號“InfoQ”(ID:infoqchina),作者李曉清、董澤光;36氪經(jīng)授權(quán)發(fā)布。
消息推送作為移動 APP 運(yùn)營中的一項(xiàng)關(guān)鍵技術(shù),已經(jīng)被越來越廣泛的運(yùn)用。本文追溯了推送技術(shù)的發(fā)展歷史,剖析了其核心原理,并對推送服務(wù)的關(guān)鍵技術(shù)進(jìn)行深入剖析,圍繞消息推送時(shí)產(chǎn)生的服務(wù)不穩(wěn)定性,消息丟失、延遲,接入復(fù)雜性,統(tǒng)計(jì)缺失等問題,提供了一整套平臺級的高可用消息推送解決方案。實(shí)踐中,借助于該平臺,不僅能提能顯著提高消息到達(dá)率,還能提高研發(fā)效率,并道出了移動開發(fā)基礎(chǔ)設(shè)施的平臺化架構(gòu)思路。 推送基礎(chǔ)
移動互聯(lián)網(wǎng)蓬勃發(fā)展的今天,大部分手機(jī) APP 都提供了消息推送功能,如新聞客戶端的熱點(diǎn)新聞推薦,IM 工具的聊天消息提醒,電商產(chǎn)品促銷信息,企業(yè)應(yīng)用的通知和審批流程等等。推送對于提高產(chǎn)品活躍度、提高功能模塊使用率、提升用戶粘性、提升用戶留存率起到了重要作用,作為 APP 運(yùn)營中一個(gè)關(guān)鍵的免費(fèi)渠道,對消息推送的合理運(yùn)用能有效促進(jìn)目標(biāo)的實(shí)現(xiàn)。
推送最早誕生于 Email 中,用于提醒新的消息,而移動互聯(lián)網(wǎng)時(shí)代則更多的運(yùn)用在了移動客戶端程序。要獲取服務(wù)器的數(shù)據(jù),通常有兩種方式:第一種是客戶端 PULL(拉)方式,即每隔一段時(shí)間去服務(wù)器獲取是否有數(shù)據(jù);第二種是服務(wù)端 PUSH(推)方式,服務(wù)器在有數(shù)據(jù)的時(shí)候主動發(fā)給客戶端。
很顯然,PULL 方案優(yōu)點(diǎn)是簡單但是實(shí)時(shí)性較差,我們也可以通過提高查詢頻率來提高實(shí)時(shí)性,但這又會造成電量、流量的消耗過高,反之 PUSH 方案基于 TCP 長連接方式實(shí)現(xiàn),消息實(shí)時(shí)性好,但是由于要保持 APP 客戶端和服務(wù)端的長連接心跳,也會帶來額外的電量和流量消耗。因此在整體架構(gòu)設(shè)計(jì)中需要折中平衡,目前主流的推送實(shí)現(xiàn)方式都是基于 PUSH 的方案。
移動推送的三種實(shí)現(xiàn)方式
目前移動推送技術(shù)實(shí)現(xiàn)方式主要有以下三種:
輪詢方式(PULL)
客戶端和服務(wù)器定期的建立連接,通過消息隊(duì)列等方式來查詢是否有新的消息,需要控制連接和查詢的頻率,頻率不能過慢或過快,過慢會導(dǎo)致部分消息更新不及時(shí),過快會消耗更多的資源(流量、電量等),對用戶體驗(yàn)有較大傷害。
短信推送方式(SMS PUSH)
通過短信發(fā)送推送消息,并在客戶端植入短信攔截模塊(主要針對 Android 平臺),可以實(shí)現(xiàn)對短信進(jìn)行攔截并提取其中的內(nèi)容轉(zhuǎn)發(fā)給 App 應(yīng)用處理,這個(gè)方案借助于運(yùn)營商的短消息,能夠保證最好的實(shí)時(shí)性和到達(dá)率,但此方案對于成本要求較高,開發(fā)者需要為每一條 SMS 支付費(fèi)用。
長連接方式(PUSH)
移動 Push 推送基于 TCP 長連接實(shí)現(xiàn), 客戶端主動和服務(wù)器建立 TCP 長連接之后, 客戶端定期向服務(wù)器發(fā)送心跳包用于保持連接, 有消息的時(shí)候, 服務(wù)器直接通過這個(gè)已經(jīng)建立好的 TCP 連接通知客戶端。盡管長連接也會造成一定的開銷,對于輪詢和 SMS 方案的硬傷來說,目前已經(jīng)是最優(yōu)的方式,而且通過良好的設(shè)計(jì),可以將損耗降至最低。不過,隨著客戶端數(shù)量和消息并發(fā)量的上升,對于消息服務(wù)器的性能和穩(wěn)定性要求提出了非常大的考驗(yàn)。因此,就難度而言,此方式代價(jià)最高。
推送解決方案
基于 TCP 長連接的方式是主流的推送方式,基于該推送方式逐步發(fā)展出系統(tǒng)級、應(yīng)用級一系列的推送解決方案。
系統(tǒng)級方案
iOS 平臺(APNs)
iOS 在系統(tǒng)層面與蘋果 APNs(Apple Push Notification service)服務(wù)器建立連接,應(yīng)用通過觀察者模式向 ioS 系統(tǒng)注冊關(guān)注的消息,系統(tǒng)收到 APNs Server 消息后轉(zhuǎn)發(fā)到相應(yīng)的應(yīng)用程序,整個(gè)過程很清晰,并且所有 APP 都共用同一個(gè)系統(tǒng)級的連接,減少了系統(tǒng)開銷,雖然 APNs 能無障礙的訪問,但實(shí)際使用過程中,發(fā)現(xiàn)延時(shí)和丟消息的情況偶有發(fā)生。
Android 平臺(C2DM)
Android 的 C2DM(Android Cloud to Device Messaging)采取與 iOS 類似的機(jī)制,都是由系統(tǒng)層面來支持消息推送,但是由于 Google 的服務(wù)在國內(nèi)不能穩(wěn)定的訪問,此方案對于中國用戶來說基本是無法使用的。
除了 Google 官方提供的方案,中國眾多的手機(jī)廠商在其定制的系統(tǒng)中也內(nèi)置了推送功能,如小米、華為等。
應(yīng)用級方案
第三方推送服務(wù)
鑒于 Android 平臺 C2DM 推送的不可用性,國內(nèi)涌現(xiàn)出大量的第三方推送服務(wù)提供商,采用第三方推送服務(wù)的系統(tǒng)流程如下圖:
圖 1:消息推送流程
目前應(yīng)用最為廣泛的第三方推送服務(wù)提供商包括個(gè)推、極光、友盟、小米、華為、BAT 等,絕大部分 APP 都會優(yōu)先考慮采用第三方推送服務(wù)。
自建推送服務(wù)
第三方服務(wù)在開發(fā)成本和消息到達(dá)率上表現(xiàn)都不錯(cuò),但所有信息會經(jīng)過第三方服務(wù)器,對于信息敏感類 APP 而言,有必要考慮自建一套消息推送服務(wù),能最大化保證安全,但對于自建推送服務(wù),如果從零開始來做需要解決幾個(gè)難點(diǎn):
第一,移動推送服務(wù)器對 App 客戶端海量長連接的維護(hù)管理。第二,App 客戶端如何保證 Push Service 常駐,對于 Android 我們可以通過發(fā)現(xiàn) push service 不存在可以定時(shí)拉起的方式。第三,通信協(xié)議的制定,我們可以采用開源的 XMPP 方式實(shí)現(xiàn),也可以自定義協(xié)議,不管哪種方式我們都要保證消息傳送的到達(dá)率的準(zhǔn)確性。第四,在移動互聯(lián)網(wǎng)網(wǎng)絡(luò)環(huán)境下,經(jīng)常出現(xiàn)弱網(wǎng)環(huán)境,特別是 2G、3G 等網(wǎng)絡(luò)不穩(wěn)定的情況下,如果保證消息在弱網(wǎng)環(huán)境下不重、不丟也是一個(gè)挑戰(zhàn)。
存在問題
無論是第三方推送服務(wù),還是自建推送服務(wù),在實(shí)際的使用過程中,發(fā)現(xiàn)都存在以下問題:
應(yīng)用服務(wù)端與推送服務(wù)強(qiáng)耦合。當(dāng)推送服務(wù)不可用時(shí),造成整個(gè)業(yè)務(wù)系統(tǒng)無法推送,甚無法正常工作。
缺乏 ACK 機(jī)制。推送的過程是異步的,從應(yīng)用服務(wù)端發(fā)送到推送服務(wù)時(shí),可以得知發(fā)送是否成功,但是從第三方推送服務(wù)下發(fā)到 APP 時(shí),無法得知客戶端是否接收到。iOS 平臺中,從推送服務(wù)發(fā)送到蘋果 APNs 服務(wù)時(shí),同樣無法確定 APNs 是否收到。同時(shí),第三方推送服務(wù)通常使用共享的推送通道,受其他推送方的影響,可能造成消息的延遲和丟失。
服務(wù)會被殺死。尤其在 Android 平臺上,后臺推送 service 會被各種主動或者被動原因 kill 掉,導(dǎo)致消息丟失。
缺乏消息的持久化。對于推送服務(wù)而言,消息推送是來一條推一條,無法追溯歷史消息和消息狀態(tài)。
缺乏重傳機(jī)制。整個(gè)推送過程涉及多個(gè)環(huán)節(jié),當(dāng)其中某個(gè)環(huán)節(jié)出現(xiàn)問題,造成客戶端接收不到推送的消息時(shí),就導(dǎo)致消息丟失,再無法接收到。
客戶端接入邏輯復(fù)雜。每接入一個(gè)新的 APP,都要進(jìn)行重復(fù)的接入工作,接入邏輯完全一致,代碼無法復(fù)用,需要在不同項(xiàng)目中拷貝。
客戶端與推送服務(wù)的 SDK 強(qiáng)耦合??蛻舳耸褂猛扑头?wù)的接口,而各推送服務(wù)提供的接口不統(tǒng)一,如果需要替換推送服務(wù),那么接入部分代碼需完全重寫。
缺乏數(shù)據(jù)監(jiān)控和統(tǒng)計(jì)。每個(gè)應(yīng)用每天推送了多少消息,成功到達(dá) app 多少,失敗多少,目前均沒有統(tǒng)計(jì)。
解決之道
為了解決以上問題,我們考慮基于第三方消息推送服務(wù)構(gòu)建一套移動消息推送中間件平臺,該消息平臺采用了低耦合的分層架構(gòu)設(shè)計(jì)(如圖 2 所示),分為三層:接入層、傳輸層和應(yīng)用層。其中接入層是業(yè)務(wù)方調(diào)用的入口,我們采用異步消息隊(duì)列的方式提供了較高的業(yè)務(wù)系統(tǒng)發(fā)送消息的速度,并且具備了消息緩沖功能,即使高峰期的海量消息推送對整個(gè)平臺沖擊較少,保護(hù)了推送系統(tǒng);
傳輸層會從接入層接收消息并進(jìn)行解析,對推送消息進(jìn)行合法性檢查校驗(yàn),如果消息不合法直接丟棄,同時(shí)將合法的消息進(jìn)行協(xié)議轉(zhuǎn)換并發(fā)送到對應(yīng)的第三方推送平臺;應(yīng)用層主要是提供統(tǒng)一的 SDK 供業(yè)務(wù)使用,封裝適配第三方推送平臺的 SDK 接口到統(tǒng)一的接口 SDK 中,這樣業(yè)務(wù) APP 使用方只關(guān)注統(tǒng)一封裝的 SDK 即可實(shí)現(xiàn)業(yè)務(wù)消息的操作,而不需要考慮各種濾重、校驗(yàn)等通用操作。主要功能包括:
屏蔽推送接口,實(shí)現(xiàn)業(yè)務(wù)與推送服務(wù)解耦,提供一套通用的客戶端 SDK,簡化客戶端接入。
實(shí)現(xiàn)多點(diǎn)接入,可同時(shí)接入多套推送服務(wù),根據(jù)歷史推送成功率動態(tài)選擇最優(yōu)推送路徑,當(dāng)一條路徑失效可選擇備用路徑進(jìn)行推送,保證消息推送萬無一失。
引入消息持久化機(jī)制,方便追溯和統(tǒng)計(jì)。
引入消息的 ACK 機(jī)制和重傳機(jī)制,提高消息的到達(dá)率。
實(shí)現(xiàn)數(shù)據(jù)監(jiān)控和統(tǒng)計(jì)機(jī)制,提供相關(guān)數(shù)據(jù)的統(tǒng)計(jì)分析,和報(bào)警預(yù)警功能。
提供 web 管理后臺,便于進(jìn)行 APP 設(shè)置、推送設(shè)置、查看數(shù)據(jù)報(bào)表,提高系統(tǒng)維護(hù)的工作效率。
整個(gè)系統(tǒng)設(shè)計(jì)由三部分組成:移動推送平臺、客戶端 SDK、應(yīng)用管理界面(第三方推送服務(wù)和自建推送服務(wù)統(tǒng)稱為推送服務(wù))。
圖 2:系統(tǒng)架構(gòu)
移動推送平臺提供統(tǒng)一的服務(wù),對于應(yīng)用層屏蔽推送服務(wù)接口,且實(shí)現(xiàn)推送服務(wù)可動態(tài)輪替。推送平臺將接收到的消息持久化到數(shù)據(jù)庫中,方便進(jìn)行消息推送失敗后的重發(fā),以及后續(xù)數(shù)據(jù)的統(tǒng)計(jì)分析。
客戶端 SDK 對 App 提供統(tǒng)一的使用接口,屏蔽推送服務(wù) SDK 使用細(xì)節(jié),且實(shí)現(xiàn)多種推送 SDK 可替換,隱藏 SDK 復(fù)雜的接入過程,方便使用。
應(yīng)用管理系統(tǒng)面向 App 開發(fā)人員,實(shí)現(xiàn)應(yīng)用申請,推送服務(wù)配置,消息查詢與管理,數(shù)據(jù)統(tǒng)計(jì)與分析。
主要流程
消息推送涉及的主要模塊是消息推送平臺和客戶端 SDK,主要流程如下圖所示:
圖 3:消息推送中間件核心流程
正常情況下,消息推送過程如下:
系統(tǒng)接收到業(yè)務(wù)方的推送請求后,首先進(jìn)行權(quán)限的驗(yàn)證,這包括應(yīng)用 appKey 的驗(yàn)證、接口參數(shù)的驗(yàn)證、黑名單驗(yàn)證等。
驗(yàn)證不通過,返回錯(cuò)誤信息;驗(yàn)證通過后,為此條消息分配一個(gè)唯一 id(uuid),將消息內(nèi)容持久化到數(shù)據(jù)庫中,此時(shí)消息的狀態(tài)為待發(fā)送。
消息進(jìn)入推送隊(duì)列中,將之后推送接口請求的響應(yīng)返回給業(yè)務(wù)方。
推送隊(duì)列的消費(fèi)者從隊(duì)列中取出待發(fā)送的消息,標(biāo)記該條消息的狀態(tài)為發(fā)送中,然后調(diào)用第三方推送服務(wù)接口進(jìn)行發(fā)送。
如果調(diào)用成功,那么標(biāo)記該消息的狀態(tài)為發(fā)送成功客戶端未收到。
客戶端 SDK 在收到推送后,回調(diào)服務(wù)端接口,發(fā)送收到推送的回執(zhí);服務(wù)端收到客戶端回執(zhí)后,標(biāo)記消息狀態(tài)為發(fā)送成功客戶端已收到。
對于推送過程中可能出現(xiàn)的異常情況,總結(jié)如下:
在調(diào)用第三方推送服務(wù)接口時(shí),可能出現(xiàn)調(diào)用失敗的情況;此時(shí)需要標(biāo)記消息的狀態(tài)為發(fā)送失敗,留待重發(fā)。
在調(diào)用第三方推送服務(wù)接口成功后、第三方推送服務(wù)在下發(fā)至客戶端的過程中,可能由于某種原因,造成客戶端無法收到消息;此時(shí)消息的狀態(tài)為發(fā)送成功客戶端未收到,對于這種狀態(tài),需要重發(fā)。
客戶端在收到推送的消息后、向服務(wù)端發(fā)送 ACK 回執(zhí)時(shí),可能由于網(wǎng)絡(luò)環(huán)境的問題,造成服務(wù)端沒有收到客戶端發(fā)送的回執(zhí),此時(shí)消息的狀態(tài)為發(fā)送成功客戶端未收到,對于這種狀態(tài),需要重發(fā)。
消息在重發(fā) N 次(N 次可配置)、仍然沒有進(jìn)入發(fā)送成功客戶端已收到的狀態(tài),那么將不再進(jìn)行自動重發(fā);管理界面將提供手動重發(fā)消息的操作入口,如有需要,可以手動再進(jìn)行重發(fā)。監(jiān)控平臺對于一直重復(fù)不成功的消息會報(bào)警通知操作人員,這樣操作人員可以及時(shí)通過手動方式處理。
根據(jù)消息發(fā)送流程,可以得到消息在生命周期中狀態(tài)的變遷如下圖:
圖 4:消息狀態(tài)機(jī)
重發(fā)機(jī)制
消息重發(fā)主要存在三種場景:系統(tǒng)啟動時(shí),查詢所有的發(fā)送失敗或發(fā)送成功未收到客戶端回執(zhí)的消息,加載到推送隊(duì)列重發(fā);系統(tǒng)運(yùn)行時(shí),后臺線程定時(shí)查詢需要重發(fā)的消息,進(jìn)入推送隊(duì)列;手動觸發(fā)時(shí),直接將消息加入推送隊(duì)列。
由于消息推送中間件服務(wù)通常要求高可用,為分布式部署,消息重發(fā)必須保證在單一節(jié)點(diǎn)執(zhí)行,且保證只發(fā)送一次。需采用分布式鎖的方式,保證重發(fā)只發(fā)一次,主流實(shí)現(xiàn)方式有三種:
ZooKeeper:通過競爭創(chuàng)建臨時(shí)節(jié)點(diǎn)的方式獲取鎖。
Redis:Redlock 是 Redis 作者的提出了一種分布式鎖的算法,基于 Redis 實(shí)現(xiàn),該算法實(shí)現(xiàn)了一種更安全、可靠的分布式鎖管理。
數(shù)據(jù)庫:如使用 MySQL 的 GET_LOCK 函數(shù)
對于每種鎖機(jī)制的特點(diǎn)本文不詳細(xì)介紹,根據(jù)實(shí)際應(yīng)用需要任選一種即可。
由于 iOS 平臺和 Android 平臺的差異,消息重發(fā)需要考慮平臺差異性。
使用第三方推送時(shí),如果 iOS 應(yīng)用在前臺運(yùn)行,那么將通過第三方推送維護(hù)的長連接,以透傳的方式直接下發(fā)到 APP,稱為應(yīng)用內(nèi)消息;而當(dāng) APP 在后臺時(shí),則第三方推送將消息推送到 APNs,由 APNs 推送到 APP,稱為 APNs 通知。當(dāng)通過 APNs 推送時(shí),手機(jī)在收到消息后將在頂部的通知欄出現(xiàn)相關(guān)推送內(nèi)容,這一行為是系統(tǒng)級別的,APP 無法控制??赡軙霈F(xiàn)這一問題:當(dāng) APP 在后臺或者手機(jī)鎖屏的情況下,如果服務(wù)端重發(fā)了消息,手機(jī)的通知欄將出現(xiàn)多條通知。
因此,考慮當(dāng) APP 在后臺時(shí),針對 iOS 平臺的消息不再進(jìn)行重發(fā);只有當(dāng) APP 進(jìn)入前臺,才重新進(jìn)行重發(fā)。APP 的活動狀態(tài)通過第三方推送服務(wù)的 api 可以獲取到。
Android 平臺不存在該問題。
由于消息重發(fā)可能會造成客戶端收到重復(fù)消息,需要在客戶端進(jìn)行消息去重。服務(wù)端為每一條消息分配了一個(gè)唯一 id,重發(fā)時(shí)唯一 id 不變??蛻舳诵枰4媸盏降拿恳粭l消息,在接收到新消息時(shí)首先根據(jù)唯一 id 判斷是否已經(jīng)收到了這條消息,如收到則不響應(yīng)??蛻舳吮4嫦⒖梢圆捎?sqlite 數(shù)據(jù)庫。
安全和控制
客戶端 SDK 與服務(wù)端的通信過程使用 appKey 和 appSecret 進(jìn)行權(quán)限控制。appKey 是服務(wù)端為每個(gè) app 分配的唯一標(biāo)識,appSecret 是服務(wù)端為每個(gè) app 分配的秘鑰。
客戶端 SDK 在請求服務(wù)端 HTTP 接口時(shí),會將 appKey+appSecret 做一次簽名,將簽名值作為簽名 sign 參數(shù),與其他請求參數(shù)(業(yè)務(wù)參數(shù) +appKey)一同傳到服務(wù)端;服務(wù)端拿到請求參數(shù)后,也先用 appKey+appSecret 做一次簽名,比較和客戶端傳來的 sign 參數(shù)是否一致,從而完成權(quán)限驗(yàn)證過程。為了能夠?qū)崿F(xiàn)靈活控制推送與否,可實(shí)現(xiàn)黑名單管理的功能。處于黑名單內(nèi)的 app 客戶端不再進(jìn)行消息的推送。黑名單控制的粒度到賬號級別,也可以根據(jù)實(shí)際業(yè)務(wù)需要進(jìn)行分組管理。
在某些業(yè)務(wù)場景中,需要對消息進(jìn)行過濾,分析,做出相應(yīng)的處理甚至預(yù)警,借助于消息推送平臺,都能方便的實(shí)現(xiàn)。
SDK 設(shè)計(jì)
客戶端 SDK 是基于推送服務(wù)的 SDK 封裝實(shí)現(xiàn),對外提供統(tǒng)一的使用接口。SDK 的使用者不再關(guān)注具體使用了哪些第三方推送、推送服務(wù)的接入細(xì)節(jié)。實(shí)現(xiàn)與推送服務(wù)的充分解耦,降低開發(fā)和使用成本。
由于 iOS 和 Android 平臺的差異性,在客戶端 SDK 的封裝上存在差異,下面分別介紹兩個(gè)平臺的 SDK 封裝方式。
iOS 平臺
SDK 提供啟動和停止的方法;同時(shí)定義一個(gè) protocol,包含 SDK 提供的接口。SDK 在收到消息或出現(xiàn)錯(cuò)誤時(shí)將會回調(diào) protocol 中的接口。
由于推送的接入涉及 AppDelegate 的生命周期方法,為避免 SDK 使用者關(guān)注這些繁瑣的細(xì)節(jié),SDK 使用 Aspects 的方式,將推送時(shí)相應(yīng)的處理函數(shù) hook 到 AppDelegate 的生命周期方法上。
Android 平臺
在 Android 中使用 Receiver 組件來接收收到的消息。一個(gè)基本的配置如下所示:
流程如下:當(dāng)推送服務(wù)的 SDK 在接收到推送過來的消息后,將發(fā)送廣播,這個(gè)廣播的用 intent-filter 標(biāo)識,當(dāng)應(yīng)用中的 Receiver 代碼注冊了這個(gè) intent-filter,就可以接收到廣播,并進(jìn)行后續(xù)處理。
系統(tǒng)管理
圖 5:后臺管理示意圖
消息后臺管理系統(tǒng)提供應(yīng)用申請、應(yīng)用服務(wù)配置、推送服務(wù)配置、消息查詢與管理等功能。
1、應(yīng)用申請
填寫應(yīng)用名、應(yīng)用描述等信息后,生成該應(yīng)用唯一的 appKey 和 appSecret。
2、應(yīng)用服務(wù)配置
為應(yīng)用選擇要使用的移動端通用服務(wù),可供選擇的有推送、反饋、版本發(fā)布。
3、推送服務(wù)配置
為應(yīng)用配置推送服務(wù),可供選擇個(gè)推、極光等;以及推送時(shí)使用的優(yōu)先級順序。
4、消息查詢與管理
查看應(yīng)用所發(fā)出的消息,包括消息所屬應(yīng)用、所屬賬號、消息的狀態(tài)、最終發(fā)送成功的第三方渠道、消息的來源、發(fā)送者 ip 等信息
5、數(shù)據(jù)統(tǒng)計(jì)
通過分析 message 表中的各消息的狀態(tài),可統(tǒng)計(jì)各應(yīng)用消息的發(fā)送成功率和到達(dá)率,以及哪個(gè)第三方推送的更優(yōu),方便選擇。同時(shí),提供每日、每周、每月推送消息量的統(tǒng)計(jì),并提供統(tǒng)計(jì)圖表。
高可用、高性能、高穩(wěn)定性
消息推送平臺通過無狀態(tài)設(shè)計(jì)、統(tǒng)一存儲、冗余部署方式保證了高可用,對應(yīng)的狀態(tài)數(shù)據(jù)統(tǒng)一存儲到 MySQL、Redis 中保證各個(gè)無狀態(tài)實(shí)例共享數(shù)據(jù)。
對于消息的接收處理我們通過純異步、動態(tài)多線程的方式提供了推送平臺的高性能。同時(shí)對于異步接收的消息我們通過 log append 的方式保證消息先落地然后再進(jìn)行處理,進(jìn)一步確保系統(tǒng)在異常過程中我們可以隨時(shí)恢復(fù)消息,保證不丟失。
通過質(zhì)量保障、全方位多維度監(jiān)控體系(基礎(chǔ)監(jiān)控、錯(cuò)誤日志監(jiān)控、發(fā)送數(shù)據(jù)波動監(jiān)控、進(jìn)程監(jiān)控等監(jiān)控指標(biāo))保障系統(tǒng)在出現(xiàn)問題時(shí)實(shí)現(xiàn)秒級報(bào)警、及時(shí)處理保證了消息推送平臺的高穩(wěn)定性。
寫在最后
本文介紹了一種基于第三方或自建推送服務(wù)、但又不強(qiáng)依賴特定推送服務(wù)的通用移動消息推送中間件平臺,可以實(shí)現(xiàn)安全、穩(wěn)定、可靠的消息推送功能,并提供完善的數(shù)據(jù)統(tǒng)計(jì),在實(shí)際應(yīng)用中,可以結(jié)合郵件、短信、網(wǎng)站消息、用戶留言等打造成更加通用的企業(yè)消息平臺。