推送服務已是app的標配了。架設推送服務,除可使用第3方服務商外,也有大量的開源技術可以選擇。
現在推送主要分兩塊,android推送和ios推送,在下面分別論述:
Android手機由于沒有系統的限制,當app進入了后臺后,也能運行服務,所以android的推送可以基于長連接,這就注定了android的推送服務器和1般的app后端是不1樣,技術細節上,架構上也不1樣,幸虧,現在有大量的開源軟件可以輕松地實現推送。
下面深入研究過的開源推送軟件:gopush-cluster為例,說明android推送服務的1般架構。
gopush-cluster,這是由獵豹移動開源的推送軟件,已被廣泛利用于下面的業務:
微看、獵豹閱讀器熱劇推薦,追劇提示;
游戲的游戲活動推送;
手機助手app推薦,廣告;
電池醫生實時推薦、求生手冊的實時消息;
PC毒霸的指令下發(web換膚,升級提示),漏洞泡泡等;
PC手機助手實時游戲、廣告推薦;
PC獵豹閱讀器上WEB
和gopush-cluster架構師毛劍討論技術,很感謝毛劍同學不厭其煩的解答,幫助我理清了很多gopush-cluster設計上不容易明白的地方,而且毛劍同學還是個美男架構師哦^-^
下面對gopush-cluster的講授來源于毛劍同學的博客,決定真實可靠的資料:
gopush-cluster的架構圖:
主要分為3個模塊來開發,comet/web/message。
(1)comet
主要負責消息排隊、消息推送和和客戶真個連接保護;整套系統根據是消息ID順序原則獲得消息(客戶端本地獲得最大的消息是1,那末以后獲得的消息就是大于1的,獲得離線消息的時候也要從上次最大消息ID來獲得),因此消息推送以后需要在comet中排隊然后發起RPC給message實現存儲。
(2)message
主要負責消息的存儲和讀寫;接受來自comet模塊的消息進行持久化,或接受web模塊的讀取消息要求獲得離線消息。message是可以部署多個節點來負載來自大量comet的推送壓力,比如不同的comet使用不同的message節點(節點無狀態),以后在comet也會做多message節點的負載均衡RPC調用和故障轉移(TODO)。
(3)web
主要負責節點詢問,和離線消息獲得和后臺節點管理等;節點詢問主要根據客戶真個定閱Key1致性hash計算出連接的comet節點地址,因此海量客戶端連接的時候可以打散到多個comet來服務;另外離線消息也是通過web接口返回給客戶真個,但是消息的讀取是通過RPC發送給message模塊的,盡可能的職責單1。web節點由于無狀態,可以部署多個web,來實現負載均衡和故障轉移。
(4)thrid-part
消息存儲現在主要依賴Redis進行消息讀寫(SortedSet),由于Sorted Set不支持int64類型的Score(我們也開發了1個支持int64 Score的分支但是由于時間緣由沒有大量測試上線),以后可能會使用HBase集群代替Redis的使用,已提供更安全的離線消息存儲(TODO)。
另外使用了Zookeeper來實現的同1個comet的故障轉移,例如comet節點1可以有1個備選節點節點2,當節點1注冊到zookeeper以后,由于機器或其他緣由宕了,這時候候會在web層觸發zookeeper的選舉選中節點2來服務。
APNS 是Apple PushNotification Service(Apple Push服務器),由于ios系統的限制,大部份利用是不允許在后臺運行并連接網絡的。在利用沒有被運行的時候,只能通過 Apple Push Notification Service (APNs) 把消息送到app。
Apns的推送原理以下圖:
推送的進程經過以下步驟:
1. 首先,安裝了具有推送功能的利用,我們的裝備在有網絡的情況下會連接蘋果推送服務器,連接進程中,APNS會驗證device_token,連接成功后保持1個長連接。
2. Provider(我們自己的服務器)收到需要被推送的消息并結合被推送裝備的device_token1起打包發送給APNS服務器。
3. APNS服務器將推送信息推送給指定device_token的裝備。
4. 裝備收到推送消息后通知我們的利用程序并顯示和提示用戶(聲音、彈出框)。
在接入apns服務進程中,有兩個問題需要注意:
1. 服務端連接到apns服務器的連接,空閑了1段時間后,apns服務器會自動斷開這個連接,這時候服務器就需要做重連操作。
2. 發送了無效device_token后的處理 。
為啥會有沒有效的device_token呢?當用戶卸載了app后,用戶的device_token就失效了,這個失效的device_token已被保存在數據庫中。當向apns服務器推送消息時,如果推送了這個無效的token,就會error-response。
如果有error-response,那末這條以后的通知都需要重發。隔1段時間后,這個連接會斷開,但是,在斷開前的時間,發送的device_token都會失效。所以我們斟酌重發的問題。error-response中返回的通知ID,可以幫助我們找出哪條出錯了,這樣就可以知道哪些需要重發了.
另外,APNS的feedbackservice會返回那些已卸載的裝備的device_token。在數據庫中刪除這些device_token,下次就不用再給他們發了,可以節省點資源。
在網絡上找到解決了上面兩個apns推送問題的開源軟件:
1. java方面:dbay-apns-for-java
2. python方面:apns-client
對創業公司來講,我1直推重的架構原則是“盡可能使用成熟的第3方服務和軟件,自己只負責業務邏輯”。
如果沒到達百萬級的范圍,實在沒必要架設自己的推送服務器。而且,現在所有的推送軟件,都缺1個良好的管理后臺。例如,我想知道某個用戶為啥沒收到推送,是由于推送不發送,還是發送了用戶沒收到啊?只能在海量的日志中尋覓答案,每次遇到這類問題,都是1個杯具。
--------------------------------------------------------------------------------------------------------------------------
打開鏈接 app后端系列文章總目錄 總目錄 ,能查看本人發表過的所有原創“app后端”文章。
【作者】曾健生
如果您覺得文章對你有所幫助,歡迎打賞。
微信打賞:
支付寶打賞: