淺談京東云推送----節(jié)省 穩(wěn)定 精準
移動互聯(lián)網(wǎng)時代,推送(Push)服務成為App應用不可或缺的重要組成部分。推送服務可以提升用戶的活躍度和留存率。
然而,市場現(xiàn)有推送服務一直存在不少問題。
第一、耗電。手機耗電量大,手機電池堅持不了兩天,待機時間短;
第二、不穩(wěn)定。消息丟失、重復推送、延遲送達、過期推送時有發(fā)生;
第三、無用消息,用戶收到的大量無用消息,垃圾信息滿天飛。
這些問題讓用戶很受傷。用戶很生氣,后果很嚴重,用戶可能直接就把應用卸載了,真是成也蕭何,敗也蕭何。
京東云推送是京東云平臺推出的節(jié)省、穩(wěn)定、精準的推送服務。針對耗電、不穩(wěn)定、無用消息等問題,京東云推送做了的周全的處理。本文將嘗試分析京東云推送如何解決市場現(xiàn)有推送服務存在的上述問題,實現(xiàn)節(jié)省、穩(wěn)定、精準推送。
使用傳統(tǒng)推送服務,手機上多個應用都使用推送服務時,耗電量大,手機電池堅持不了兩天 ,待機時間短。手機推送原理,就是通過建立一條手機與服務端的連接鏈路,即長連接,當有消息需要推送到手機時,通過這條鏈路發(fā)送消息。長連接需要定期發(fā)送心跳來確保鏈路一直保持,這都有電量和流量消耗。比如有5個應用都使用了某推送服務,每個應用都和后端服務器建立長連接,并定期發(fā)送心跳包,耗電、流量情況可想而知。
省電省流量。京東云推送設(shè)計多應用單服務單連接模式、使用AlarmManager定時心跳節(jié)省電量和流量。
多應用單服務單連接。手機上多個App應用共享一個Android服務一個連接。京東云推送設(shè)計了多應用單服務單連接模式。手機上多個應用使用了京東云推送,即每個應用內(nèi)嵌入了京東云推送SDK,多個應用共享一個服務JDPushService,由Service去和云端服務器建立TCP長連接,接收消息。
每個終端設(shè)備在云推送平臺有一個唯一標識Token,每個應用有唯一標識AppID. JDPushService收到云端消息后,根據(jù)消息包里的AppID,來判斷消息屬于哪個App后發(fā)送給對應的App應用。第一個應用啟動了推送服務后,其他應用啟動服務的時候,會檢查服務是否存在,如果存在就使用已啟動服務。每個應用都有機會啟動JDPushService服務,運行推送服務增加的耗電量和流量總體上會比較平均地分攤到各個應用上。多應用單服務單連接,有效解決了多應用多鏈路帶來的高耗電費流量問題。單個手機上使用京東云推送服務的應用越多,省電省流量優(yōu)勢就越明顯。
AlarmManager定時心跳。京東云推送使用AlarmManager來定時執(zhí)行心跳任務。長連接通信,如果連接一段時間沒有通訊數(shù)據(jù)時,鏈路一般會被切斷。為了防止鏈路中斷,需要發(fā)送心跳維持存活。Android手機上使用Timer 執(zhí)行定時任務時,需要用WakeLock讓Cpu 保持喚醒狀態(tài),會大量消耗手機電量,縮短手機待機時間。而用AlarmManger來執(zhí)行定時任務,Cpu可以正常休眠,只有在需要運行任務時醒來很短時間,極大的提升手機的待機時間。
節(jié)省服務器。京東云推送單服務器能夠支撐200萬(C2000K)以上的連接數(shù)。單服務器承載同時連接數(shù)越多,所需服務器就越少,成本越低。保證大量的在線連接穩(wěn)定可靠地通信,對后端連接服務器有很大挑戰(zhàn)。如何提升單服務器連接數(shù),保證連接穩(wěn)定可靠的推送數(shù)據(jù),是推送服務的技術(shù)難點。
Object pool緩存可重用的對象。會話服務器上承載了大量的終端連接,每個Session連接處理、心跳包、回執(zhí)、命令處理的結(jié)構(gòu)和過程都是一樣的,京東云推送使用Object pool緩存一組可重用的對象,減少了頻繁動態(tài)創(chuàng)建對象帶來的內(nèi)存分配和回收資源消耗。和動態(tài)分配內(nèi)存相比,分配和回收速度快很多。另外,對每個對象和處理細節(jié),充分優(yōu)化內(nèi)存使用,持續(xù)優(yōu)化。內(nèi)存瓶頸會限制服務器能夠接入的用戶連接數(shù),通過Object pool 、各處理對象細節(jié)優(yōu)化,極大提升了內(nèi)存使用效率。
多核并行化。將任務調(diào)度到服務器所有Cpu核心上,并行處理。會話服務器上承載了大量的終端連接,Session會話連接和消息處理時,盡量充分利用現(xiàn)代服務器普遍具有的多核特性,將任務并行化,將所有任務調(diào)度到所有CPU核心上,最大化的利用服務器多核計算能力,從而提升推送服務整體性能。
市場現(xiàn)有推送服務一直存在消息丟失、重復推送、延遲送達、過期推送等諸多問題,京東云推送針對這些問題,做了周詳處理。
消息丟失問題主要原因有網(wǎng)絡(luò)不穩(wěn)定、系統(tǒng)可用性差等問題引起。國內(nèi)手機網(wǎng)絡(luò)不是太穩(wěn)定,上網(wǎng)方式復雜眾多,覆蓋范圍也不是很全,另外用戶還經(jīng)常使用WIFI上網(wǎng)。網(wǎng)絡(luò)信號經(jīng)常時好時壞,網(wǎng)絡(luò)不穩(wěn)定造成消息丟失或丟包都是正常的。
不丟消息。京東云推送通過消息回執(zhí)確認機制、高可用分布式服務器集群確保不丟消息。
消息回執(zhí)確認。用戶終端每收到一條消息,會給云端發(fā)送回執(zhí)確認。消息發(fā)送給用戶終端應用后,終端JDPushService服務發(fā)送收到該消息的回執(zhí)確認給云端服務,云端把消息狀態(tài)置為已送達。手機網(wǎng)絡(luò)不穩(wěn)定造成長連接中斷時,JDPushService向云端服務發(fā)起重連時,如果未收到回執(zhí)確認并且消息未過期,云端會重新發(fā)送該消息給用戶終端,確保即使網(wǎng)絡(luò)不穩(wěn)定 ,用戶始終能收到消息。
為了防止應用重復收到同一條消息,終端JDPushService服務對最新消息做持久化,收到消息時判斷是否已收過該消息,如果未收過就發(fā)送給應用,否則不再發(fā)送。同時發(fā)送回執(zhí)給云端,有效解決重復推送問題。
高可用分布式服務器集群。系統(tǒng)可用性差也會造成消息丟失,比如消息發(fā)送處理中,系統(tǒng)出現(xiàn)意外,就有消息丟失可能。京東云推送云端采用分布式服務器集群架構(gòu),每個服務節(jié)點沒有單點,確保系統(tǒng)的高可用。各個實例節(jié)點間通過MQ通信,對每個job是否成功的反饋確認,如果worker節(jié)點在執(zhí)行job時崩潰或者退出,該job會再分發(fā)給其他woker節(jié)點執(zhí)行,確保消息處理環(huán)節(jié)不丟失。數(shù)據(jù)存儲集群提供完善的數(shù)據(jù)備份和故障轉(zhuǎn)移支持,確保數(shù)據(jù)在存儲環(huán)節(jié)不丟失。
實時送達。京東云推送點播消息1秒內(nèi)送達用戶終端。市場現(xiàn)有推送服務,消息從發(fā)出到用戶收到消息時間過長,用戶無法第一時間收到消息,推送不實時。京東云推送終端應用啟動推送服務時,會啟動一個后臺共享服務JDPushService,由該服務和云端服務建立長連接。云端服務通過這條鏈路,有消息時實時推送消息到用戶終端。移動網(wǎng)絡(luò)很不穩(wěn)定,如果TCP鏈接出現(xiàn)中斷,JDPushService服務會重新發(fā)起連接,保證通信鏈路一直可用。JDPushService是后臺服務,即使應用退出后,服務仍然可以接收應用消息并通知用戶,確保應用即使在線離線狀態(tài)下,也能實時收到最新消息。
耗時任務分解。單服務器處理能力是有限的,耗時任務拆分成多個子任務,多臺服務器同時并行處理,提升時效。比如給5000萬用戶發(fā)送一個廣播消息,需要把消息任務分解成多個子任務,多服務器同時并行處理,有效縮短消息發(fā)送處理時間。
有效期推送。京東云推送設(shè)計消息過期失效機制,確保只推送有效期內(nèi)消息。消息具有時效性,過了某個時間點的消息對用戶來說就失去了價值,同時還影響體驗。比如用戶關(guān)機一個月后開機啟動應用后,瞬間收到一個月的所有消息,用戶手機瞬間癱瘓。京東云推送對消息設(shè)置離線保存時間,如果超過離線保存時間,消息自動失效并置為歷史消息,不再對用戶推送。比如設(shè)置離線保存72小時(默認2天),發(fā)送消息時用戶沒有開機,兩天后用戶開機并啟動推送服務,這時不會收到已過期的消息。
精準推送。京東云推送提供精細化的標簽組播推送和點播推送。現(xiàn)有推送用戶經(jīng)常收到的大量無用消息,垃圾信息滿天飛。應用內(nèi)廣播每個應用終端用戶都能收到,但是未必每個用戶都需要。京東云推送提供了標簽組播和點播功能,開發(fā)者可以根據(jù)用戶的習慣、愛好、對特定產(chǎn)品偏好程度等給用戶設(shè)置標簽。用戶使用App某個預設(shè)操作時,調(diào)用京東推送SDK標簽綁定接口,給用戶綁定標簽。應用商需要對該類用戶推送特定消息時,調(diào)用標簽組播推送接口,京東云推送會定位到綁定了該標簽的所有用戶,并把消息實時推送給用戶。標簽設(shè)置粒度越細,推送的精準度越高。如果需要對某個特定用戶推送消息,可以使用點播功能推送消息。通過用標簽組播和點播功能,消息只推送給感興趣的用戶,實現(xiàn)消息精準推送。
京東云推送通過多應用單服務單連接、AlarmManager定時心跳,省電省流量;Cache pool 、多核并行化提升后端服務器單機處理能力,節(jié)省服務器;消息回執(zhí)確認機制、高可用服務器集群確保不丟消息;終端服務已收消息過濾防止消息重復推送;Android后臺服務長連接、云端耗時任務分解并行處理,實現(xiàn)實時送達;離線消息過期時間設(shè)置確保消息有效期內(nèi)推送;精細化標簽組播和點播有效提升消息推送精準度。京東云推送通過這一系列策略、技術(shù)實現(xiàn),為開發(fā)者提供一個節(jié)省、穩(wěn)定、精準的推送服務。
作者簡介:康新榮,京東云平臺資深架構(gòu)師,云推送項目研發(fā)負責人。10年IT行業(yè)研發(fā)經(jīng)驗,在云計算、NoSQL、分布式、高并發(fā)系統(tǒng)構(gòu)建等領(lǐng)域有豐富的經(jīng)驗。