訊息推送技術乾貨:美團實時訊息推送服務的技術演進之路

語言: CN / TW / HK

本文由美團技術團隊分享,作者“健午、佳猛、陸凱、馮江”,原題“美團終端訊息投遞服務Pike的演進之路”,有修訂。

1、引言

傳統意義上來說,實時訊息推送通常都是IM即時通訊這類應用的技術範疇,隨著移動端網際網路的普及,人人擁有手機、隨時都是“線上”已屬常態,於是訊息的實時觸達能力獲得了廣泛的需求,已經不再侷限於IM即時通訊這類應用中。

對於美團這種移動端“入口”級應用來說,實時訊息的推送能力已經深入整個APP的方方面面。目前美團應用中使用的推送技術,是一個被命名為Pike的一套易接入、高可靠、高效能的雙向訊息實時投遞服務

本文將首先從Pike的系統架構升級、工作模式升級、長穩保活機制升級等方面介紹2.0版本的技術演進,隨後介紹其在直播、遊戲等新業務場景下的技術特性支援,並對整個系統升級過程中的技術實踐進行了總結,希望本文能給訊息實時推送服務感興趣或從事相關工作的讀者以幫助和啟發。

2、相關文章

實時訊息推送技術文章參考:

  1. 魅族2500萬長連線的實時訊息推送架構的技術實踐分享
  2. 專訪魅族架構師:海量長連線的實時訊息推送系統的心得體會
  3. 百萬線上的美拍直播彈幕系統的實時推送技術實踐之路
  4. 京東京麥商家開放平臺的訊息推送架構演進之路
  5. 解密“達達-京東到家”的訂單即時派發技術原理和實踐
  6. 長連線閘道器技術專題(四):愛奇藝WebSocket實時推送閘道器技術實踐
  7. 喜馬拉雅億級使用者量的離線訊息推送系統架構設計實踐
  8. 微信直播聊天室單房間1500萬線上的訊息架構演進之路
  9. 百度直播的海量使用者實時訊息系統架構演進實踐
  10. 技術乾貨:從零開始,教你設計一個百萬級的訊息推送系統

美團技術團隊分享的其它文章:

  1. 美團點評的移動端網路優化實踐:大幅提升連線成功率、速度等
  2. 深度解密美團的分散式ID生成演算法

3、v1.0的前世今生

3.1 v1.0 的誕生背景

2015年,美團誕生了Shark終端網路通道,為公司移動端提供長連代理加速服務。Shark通過網路接入點的全球多地部署和保持長連來提升網路請求的端到端成功率,降低端到端延時,從而提升使用者體驗。

Pike 1.0是基於Shark長連通道實現的應用內推送服務。由於底層傳輸基於Shark長連通道,使得Pike 1.0天生便具有了低延時、高可靠、防DNS劫持等優秀基因。目前Pike 1.0在美團內部的即時通訊聊天、營銷推送、狀態下發、配置同步等業務場景都有廣泛使用。

3.2 v1.0 的工作流程

Pike 1.0 移動端SDK會在每次長連線建立成功後:

  • 1)使用APPID、裝置唯一標識UnionID(美團唯一標識、點評唯一標識等)向伺服器發起註冊;
  • 2)在註冊成功之後業務服務端就可以通過Pike 1.0服務端SDK提供的介面,主動向裝置的App推送訊息;
  • 3)服務端推送的訊息通過長連線通道抵達客戶端,最後通過註冊的回撥介面投遞給業務方。

整體工作流程參見下圖:

3.3 v1.0的優勢

Pike 1.0底層傳輸基於Shark長連通道。

所以Pike 1.0在以下幾個方面有不錯的表現:

  • 1)防劫持:底層通道直接使用IP直連,省去DNS解析耗時的同時也避免了被DNS劫持的風險;
  • 2)低延時:Shark長連線採用就近接入點長連線的方式,省去了傳統HTTP需要多次建連、握手的消耗,端到端資料傳輸延時相比HTTP大幅縮短;
  • 3)安全高:Shark採用自定義二進位制協議進行資料傳輸,進行了通道級別的TLS加密,防篡改,更安全;
  • 4)體驗好:Pike 1.0與Shark共享服務叢集,Shark長連通道在海外多地都部署了接入點,代理加速接入,網路延時及成功率表現要優於常規請求。

PS:行動網路下HTTP、DNS的優化文章,可以看看下面這幾篇:

  1. 全面瞭解移動端DNS域名劫持等雜症:原理、根源、HttpDNS解決方案等
  2. 美圖App的移動端DNS優化實踐:HTTPS請求耗時減小近半
  3. 百度APP移動端網路深度優化實踐分享(一):DNS優化篇

3.4 v1.0的技術痛點

Pike 1.0作為Shark的衍生產品固然有其閃光的地方,但是對Shark的強依賴所帶來的痛點更是讓開發人員叫苦不迭,主要痛點如下。

3.4.1)程式碼結構耦合:

在客戶端SDK方面,Pike 1.0程式碼與Shark程式碼結構耦合,共用底層通道建連、資料加解密、二進位制協議等邏輯。

Pike 1.0與Shark程式碼結構示意圖:

耦合帶來的弊端一:程式碼優化升級困難。針對一個SDK的變更經常需要更多地考慮對另一個SDK是否有負面影響,是否影響面可控,這就無端地增加了開發成本。

耦合帶來的弊端二:Shark與Pike 1.0的網路配置環境共用,如上圖所示,通過DebugPanel對SharkTunnel進行網路環境配置都會同時對Shark和Pike 1.0生效,但是業務方在使用的時候往往只關注其中的一個SDK,不同SDK之間的相互影響引入了很多客服問題,也給客服問題的排查帶來了較多幹擾因素。

3.4.2)賬號體系混亂:

Pike 1.0在同一個App上只支援一種裝置唯一標識UnionID,不同App上註冊使用的UnionID會有不同,例如美團使用美團唯一標識,點評則使用點評唯一標識。

假如一個業務只在一個App上使用的話Pike 1.0自然可以很好地工作,但是同一個業務有可能需要在多個App上同時使用(如下圖所示),如果業務方不對賬號體系進行相容的話,美團App上使用點評唯一標識作為推送標識的業務將無法工作,點評App上使用美團唯一標識作為推送標識的的業務也會無法工作。

這就導致同一個業務在不同App上的推送標識ID邏輯會非常複雜,後端要同時維護多套賬號體系之間的對映,才能解決賬號體系混亂的問題。

Pike 1.0賬號體系不相容示意圖:

3.4.3)推送連線不穩定:

Pike 1.0由於共用Shark的通道邏輯而缺乏推送場景專項優化,在檢測通道異常、斷連恢復等方面表現不夠優秀。在通道可用性上,Shark與Pike 1.0關注的SLA也有著很大的不同。

例如:Shark在長連線通道不可用的情況下,可以通過降級短連線來規避業務網路請求持續失敗所帶來的成功率下降問題。但是對於Pike 1.0此時如果通道不能快速恢復的話就會造成業務訊息投送失敗,將直接影響訊息投遞成功率。所以Shark通道針對連線保活的公共邏輯並不能完美地應用在Pike 1.0業務場景上。

雖然Pike 1.0在Shark通道的基礎上進一步在協議層強化了心跳探測機制以提高通道可用性,但通道不能及時檢測異常還是時有發生。

此外:Pike 1.0內部使用的事件分發技術的可靠性還暫時沒能達到100%,零星地會上報一些異常斷連而導致推送不成功的客服問題。

綜上:針對推送連線不穩定專項優化的訴求也就不斷被提上日程。

3.5 v2.0的誕生

Pike 1.0現有的技術痛點在業務場景日益豐富的現狀下遭遇了諸多挑戰。

為求解決Pike 1.0現有在Android和iOS平臺運營上遇到的問題:

  • 1)我們重新梳理產品架構與程式碼實現;
  • 2)與基礎技術部另一個服務於H5的訊息投遞服務Pike Web進行產品融合。

進而推出全新的升級產品——Pike 2.0。

下圖展示了Pike 2.0的產品全景。針對Pike 1.0的現狀,Pike 2.0前後端都做了諸多優化,包括技術架構升級、叢集獨立、協議擴充套件等。

其中在客戶端方面Pike 2.0提供了基於多語言實現服務於多平臺的SDK,在服務端方面Pike使用部署Java應用的分散式叢集來提供服務。

Pike 2.0產品全景圖:

以下內容將主要從客戶端視角,詳細闡述Pike 2.0 客戶端SDK的技術方案設計,從原理上說明Pike 2.0帶來的技術優勢。

4、v2.0架構設計

針對上文提及的Pike 1.0程式碼結構耦合的技術痛點,Pike 2.0進行了全新的架構升級,在程式碼結構、環境配置、服務叢集等方面上都與Shark保持產品隔離。

4.1 設計思想

經過接近一年的技術積累與沉澱,從Shark提煉的TunnelKit長連核心元件和TNTunnel通用通道元件已經趨於穩定,所以Pike 2.0選擇基於TunnelKit與TNTunnel來構建雙向訊息通道服務。

具體優勢有:

  • 1)Pike 2.0基於TunnelKit長連核心構建,能有效地複用現有長連線控制相關的功能,減少不必要的開發工作;
  • 2)Pike 2.0能夠共享TNTunnel的相關通用特性,如Shark協議封裝、資料加解密等,後期維護成本較小;
  • 3)Pike 2.0協議作為Shark協議的Payload傳輸,可以靈活定製自己特性相關的協議。

4.2 整體架構

客戶端架構演進圖:

整體架構如上圖所示,包括:

  • 1)Pike介面層;
  • 2)Pike通道層;
  • 3)TNTunnel通道層;
  • 4)TunnelKit長連核心層。

4.2.1)介面層:

Pike介面層旨在為主流前端技術棧中所有需要應用內訊息服務的業務提供簡潔可靠的介面。

主要是:

  • 1)Pike 2.0提供了 Android、iOS、MRN等公司主流技術棧的接入SDK,業務可以根據自己的需求靈活選擇;
  • 2)Pike 2.0針對不同的訊息QPS,設計了兩種不同Client(詳見下方);
  • 3)Pike 2.0針對線上Pike 1.0系統提供了業務無感的遷移方案,業務方無需任何人力投入便可以從之前的Pike 1.0系統遷移至Pike 2.0系統來進行訊息的收發。

針對第 2)點,我們是這樣設計的:

  • 1)對於訊息量超過50條每秒的業務,例如直播彈幕推送,我們推薦接入聚合訊息Client;
  • 2)對於訊息量較小的其他業務,普通訊息Client則可以滿足需求。

4.2.2)通道層:

Pike通道層是特性的實現層,所有Pike介面層的API呼叫都會通過執行緒排程轉變成封裝的Task在Pike通道層完成具體的操作,Pike通道層是單執行緒模型,最大程度規避掉了執行緒安全問題。

Pike特性如下:

  • 1)斷線重連:鑑於長連線的不穩定特徵,Pike 2.0通道通過斷線重連機制來使的業務方可以認為在網路沒有發生故障的情況下是持續可用的;
  • 2)業務鑑權:業務後端可以通過Pike 2.0通道對連線的監控來感知連線變更,同時對接入網路的客戶端裝置進行可用性判別;
  • 3)別名機制:針對不同業務方對業務標識做了隔離,每個業務可以自定義標識ID,解決了Pike 1.0同一個App平臺不同業務必須強制使用相同標識ID的痛點;
  • 4)上/下行訊息:Pike 2.0是雙向通道服務,不僅支援Pike 1.0原有的訊息推送能力,即服務端向客戶端傳送下行訊息;同時也支援客戶端主動傳送訊息,即客戶端向服務端傳送上行訊息。業務只要通過Pike 2.0系統便可以形成訊息的閉環;
  • 5)分組/聚合訊息:Pike 2.0支援訊息分組和訊息聚合來滿足高QPS業務場景的使用。其中訊息分組表示業務可以通過自定義標籤來對一組使用者進行訊息廣播;訊息聚合表示將短時間內井噴式的訊息進行聚合下發以提高系統的吞吐量;
  • 6)訊息保序:Pike 2.0支援同一客戶端傳送的上行訊息有序投遞到固定的業務伺服器;
  • 7)獨立通道:Pike 2.0預設所有業務是使用一條共享的通道,針對業務量大或者對吞吐量有要求的業務可以自動切換獨享的通道來保證訊息的投遞成功率和時延;
  • 8)通道保活:Pike 2.0在連線保活的基礎上增加了通道巡檢,能夠在檢測到異常的情況下自動重啟通道,確保在要求長穩的環境下進一步提升通道可用性。

4.2.3)TNTunnel通道層:

TNTunnel通道層是封裝通用通道邏輯的功能層,主要涉及通道狀態管理、協議封裝、資料加解密等通用核心模組,是將通用通道邏輯從原先Shark通道中提煉而成的獨立分層。

Pike協議雖然是構建在現有Shark協議之上的應用層協議,但是Pike通道已經和原先的Shark通道在邏輯上完全解耦。

  • 一方面,Pike 2.0會最大限度地複用Shark協議已成熟的技術,但是又不依賴於原有的Shark邏輯;
  • 另一面,後續涉及二進位制協議、安全協議等協議方面的升級優化都可以同時服務於Pike 2.0。

4.2.4)TunnelKit長連核心層:

TunnelKit長連核心層主要功能是對接Socket來處理TCP或者UDP資料的傳送與接收,管理各個連線的可用性等。

每條Pike 2.0通道在TunnelKit中都是維護一條連線的,通過心跳保活機制和連線管理來保證在網路環境正常的情況下永遠有一條連線來承載Pike資料。

TunnelKit作為所有通道層的基礎,是決定上層長連線通道穩定性最重要的一層。

5、v2.0工作機制

在進行了全新推送架構升級的基礎上,Pike針對上文提及的Pike 1.0賬號體系混亂、推送連線不穩定的痛點重新設計並完善了工作機制。

其中,PikeClient作為Pike系統對接業務方的門戶,在整個Pike 2.0系統中起著至關重要的作用,本節將以PikeClient為切入點介紹其工作機制。

5.1 PikeClient生命週期

為了更好地維護Pike 2.0內部狀態,PikeClient使用狀態機來負責生命週期管理。

PikeClient生命週期圖:

如上圖所示,PikeClient生命週期主要包括如下幾個部分:

  • 1)onStart:該狀態是業務方呼叫StartClient或者RestartClient之後進入的狀態,此時PikeClient已經正常啟動,之後Pike 2.0內部會發起業務鑑權並根據鑑權結果流轉到其他的狀態,如圖所示如果業務鑑權失敗則進入onStop狀態,如果業務鑑權成功則進入running狀態;
  • 2)onStop:該狀態是業務方呼叫StopClient或者業務鑑權失敗之後進入的狀態,此時PikeClient已經停止工作,客戶端進入該狀態之後需要Restart才能重新使用;
  • 3)running:該狀態是PikeClient長穩工作的狀態,此時Pike 2.0等待響應服務推送的下行訊息或者隨時準備傳送上行訊息。作為雙向訊息通道,Pike 2.0處理上下行訊息的能力是完全並行的;
  • 4)onReceive: 該狀態是PikeClient成功接收到下行訊息之後進入的狀態,Pike 2.0將接收到的訊息投遞給業務方之後重新進入running狀態等待下一次操作;
  • 5)onSendSuccess/onSendFailure:該狀態是PikeClient傳送上行訊息之後進入的狀態,業務方可以通過監聽該狀態來獲取本次訊息傳送的結果。

通過基於狀態機的生命週期管理,既嚴格定義了PikeClient的工作流程,也可以準確監控其內部狀態,提高了PikeClient的可維護性。

5.2 PikeClient工作模式

針對Pike 1.0混亂的賬號體系痛點,Pike 2.0設計了全新的工作模式。

如下圖所示,Pike通過通道代理模組提供共享通道和獨立通道兩種模式來滿足不通業務場景的需求。

5.2.1)共享通道模式:

共享通道模式是Pike 2.0基本的工作模式,新增的業務方在預設情況下都會使用該模式接入Pike 2.0。

在Pike 2.0中PikeClient與Pike通道服務是多對一的共享關係,每個業務方都會有自己的PikeClient,每個PikeClient都可以自定義訊息推送標識ID而避免使用全域性標識ID。業務後端可以精簡推送標識邏輯,避免同時維護多套賬號體系。

不同業務的PikeClient僅在接入層面做了業務隔離,在Pike 2.0通道中會由Pike通道服務完成統一的管理。這種多對一的共享關係使得所有Pike業務共享Pike 2.0通道特性,同時又可以針對每個業務的使用場景設定其特定的訊息處理能力,每個接入Pike 2.0的業務方都只需要關注其自己的PikeClient即可。

5.2.2)獨立通道模式:

獨立通道模式是共享通道模式的拓展能力,Pike 2.0通過配置控制來決策是否切換至該模式。

Pike 2.0預設情況下所有業務方都是共享同一個Pike通道服務,然而鑑於業務場景的不同,每個業務對於訊息吞吐量,訊息時延等SLA指標的訴求也有差異,例如遊戲業務對於訊息時延過長的容忍性就比較差。針對特殊業務Pike 2.0提供了獨立通道切換的能力支援。

所有PikeClient都通過Pike通道代理模組來對接Pike通道服務,Pike通道代理模組可以通過開關配置來控制PikeClient與特定的Pike通道服務協同工作。通過運用代理模式,既保證了原有結構的完整性,在不需要調整Pike通道程式碼邏輯的基礎上就能夠完成獨立通道能力支援;又可以擴充套件通道切換能力,有效地管理通道切換的流程,讓Pike 2.0通道最大化提供業務能力的同時避免資源浪費。

5.3 PikeClient保活機制

PikeClient的保活完全依賴Pike 2.0通道的保活,針對Pike 1.0推送連線不穩定的痛點,Pike 2.0通道在吸收Pike 1.0在保活機制方面沉澱的技術的基礎上繼續優化,最後設計出基於心跳探測、重連機制和通道巡檢的三重保活機制。

保活機制如下圖:

5.3.1)心跳探測:

心跳探測是一種檢查網路連線狀態的常見手段,Pike長連線是TCP連線,而TCP是虛擬連線:如果實際物理鏈路中出現諸如異常網路節點等因素導致連接出現異常,客戶端和服務端並不能及時感應到連線異常,這時就會出現連線的狀態處於ESTABLISHED狀態,但連線可能已死的現象,心跳探測就是為了解決這種網路異常的技術方案。

PS:關於tcp協議為什麼還需要心跳保活,可以詳讀這篇《為何基於TCP協議的移動端IM仍然需要心跳保活機制?》。

客戶端在心跳巡檢計時器設定的心跳週期到達時判斷是否存在上次心跳超時的異常,如果心跳超時則認為該連線已經不可用了,則會從連線池移除該連線並觸發下文的重連機制。

為了更快地發現通道異常,Pike 2.0對於心跳週期與心跳超時都是可配置的,針對不同App使用的場景可以靈活地設定。

而且在每次傳送上行資料的時候都會及時檢測上次心跳是否超時,使得心跳探測結果不必等到下次心跳週期到達的時刻才知悉。

Pike 2.0並不是採用固定心跳頻率來發送心跳包,Pike 2.0會利用通道的上下行資料包來動態減少心跳包的傳送次數。

此外,智慧心跳也是Pike 2.0持續關注的話題,感興趣的讀讀下面這些:

  1. 微信團隊原創分享:Android版微信後臺保活實戰分享(程序保活篇)
  2. 微信團隊原創分享:Android版微信後臺保活實戰分享(網路保活篇)
  3. 移動端IM實踐:實現Android版微信的智慧心跳機制
  4. 移動端IM實踐:WhatsApp、Line、微信的心跳策略分析
  5. 一文讀懂即時通訊應用中的網路心跳包機制:作用、原理、實現思路等
  6. 融雲技術分享:融雲安卓端IM產品的網路鏈路保活技術實踐
  7. 正確理解IM長連線的心跳及重連機制,並動手實現(有完整IM原始碼)
  8. 一種Android端IM智慧心跳演算法的設計與實現探討(含樣例程式碼)

5.3.2)重連機制:

重連機制是Pike 2.0作為長連線通道最核心的特性,也是Pike 2.0連線穩定性建設最重要的一環。

客戶端會在傳送訊息、接收訊息和心跳探測三個環節來決策是否需要觸發重連:

  • 1)一方面,如果主動發現連線池中可用連線不足則自動啟動重連機制;
  • 2)另一面,當現有可用連線關閉時也會自動觸發重連機制。

Pike 2.0在重連的過程中會採用斐波那契數列退避演算法來發起建連請求直至建連成功:

  • 1)一方面,Pike 2.0保證只要在網路可用的情況下總能夠維持可用的長連線來服務於業務訊息;
  • 2)另方面,Pike 2.0在網路持續不可用的情況下避免連續建連使得系統滿載。

有關斷線重連這方面的文章,可以系統的讀一讀下面這些:

  1. Web端即時通訊實踐乾貨:如何讓你的WebSocket斷網重連更快速?
  2. 正確理解IM長連線的心跳及重連機制,並動手實現(有完整IM原始碼)
  3. 手把手教你用Netty實現網路通訊程式的心跳機制、斷線重連機制

PS:如果需要實踐性的程式碼,也可讀一下開源工程MobileIMSDK ,它對於im的心跳和重連機制有完整的邏輯實現,可以借鑑參考。

5.3.3)通道巡檢:

通道巡檢是在心跳探測和重連機制的基礎上進一步提升Pike 2.0穩定性的有效機制。

客戶端會根據心跳週期設定一個全域性的巡檢定時器,在每次定時器設定的時刻到達時,客戶端會觸發通道異常檢測邏輯,一旦發現異常都會嘗試重啟通道。

Pike 2.0首先會在觸發通道異常檢測的時候獲取當前通道狀態,如果通道當前沒有主動關閉但是通道處於不可用的狀態,Pike 2.0會強制執行一次自啟動。

此外,在通道巡檢的過程中,巡檢管理器會不斷收集訊息收發過程中出現的超時異常,當超時異常次數連續累計超過配置的最大閾值時,Pike 2.0會認為當前通道可用性較低,需要強制關閉並執行一次自啟動。

6、v2.0新增的技術特性

Pike 2.0作為Pike 1.0的升級版,不只是為了解決Pike 1.0的技術痛點,通過新增特性以開拓新的應用場景也是Pike 2.0關注的點。

6.1 聚合訊息

隨著公司內直播業務的興起,公司內部也有很多業務方使用Pike 1.0作為彈幕、評論、直播間控制信令等下行實時訊息的傳輸通道。

但Pike 1.0基於早先的設計架構為彈幕、評論這種短時間需要處理海量訊息的場景提供可靠服務的能力漸漸力不從心。

主要表現在QPS大幅增長時,訊息投遞成功率降低、延時增加和系統性能開銷增長等方面。Pike通過引入聚合訊息為直播場景中訊息的投遞提出更加通用的解決方案。

6.1.1)設計思想:

直播場景中涉及的訊息主要具備以下特點:

  • 1)彈幕作為一種實時互動的載體,短時間內需處理大量的圖片、文字等資訊,如果不做聚合會浪費大量的頻寬;
  • 2)直播間相比普通推送場景,由於使用者已經進入直播間,使用者行為也相對統一可控,所以更需要一種群組訊息來統一處理;
  • 3)直播間對於不同型別的訊息處理邏輯可以區分優先順序,比如抽獎、控制信令是要求可靠性不能丟棄,而對於彈幕則可根據直播間熱度、服務承受能力適當丟棄。

聚合訊息在設計上主要採用下述思想:

  • 1)從時間維度對訊息進行聚合,減少不必要的頻寬消耗;
  • 2)採用訊息分級策略,根據訊息的型別設定不同的優先順序,保證重要訊息的可靠性;
  • 3)抽象出類似直播間的聚合單元,統一管理加入聚合單元的使用者行為;
  • 4)採用客戶端主動拉取的策略;
  • 5)提供上行訊息能力,提供更完整的訊息流通路徑。

針對第 4)點:相比傳統的服務端推送策略,主動拉取是利用客戶端天然分散式的特點將使用者狀態儲存在客戶端,服務端通過減少狀態維護進而可以留出更多的資源用於業務處理。

6.1.2)方案流程:

Pike 2.0針對每個聚合單元都使用環形佇列來維護訊息列表,傳送到該聚合單元的訊息在經過優先順序過濾之後都會插入佇列tail指標標示的位置,隨著該聚合單元內訊息不斷增加最後達到最大佇列長度時,head指標會不斷移動來給tail指標騰出位置。聚合單元通過控制最大長度的環形佇列來避免訊息短時間井噴式增長帶來的服務效能問題。

客戶端在主動拉取的時候都會攜帶上一次獲取到的訊息處在環形佇列中的偏移量,這樣服務就會將偏移量標示的位置到tail指標標示的位置之間的訊息進行聚合作為本次拉取的結果一次性返回給客戶端。不同客戶端各自維護自己的偏移量,以此來避免服務端對於客戶端的狀態維護。

客戶端與服務端的具體互動如下圖所示:客戶端在加入聚合單元之後主動拉取,如果本次拉取攜帶的偏移量能夠從服務的環形佇列中獲取到聚合訊息,那麼就將訊息回撥給業務之後馬上進行下一次拉取操作。如果本次攜帶的偏移量已經位於環形佇列tail指標的位置,那麼服務端將不做任何響應,客戶端等待本次拉取超時之後開始下一次拉取操作,重複該流程直至客戶端離開該聚合單元。與此同時,業務服務端如果有訊息需要推送,則通過RPC的方式傳送給Pike服務端,訊息處理模組將執行訊息分級策略過濾之後的有效訊息插入環形佇列。

聚合訊息互動流程圖:

6.2 訊息保序

Pike 1.0在設計之初就只適用於訊息推送的場景,而Pike 2.0在其基礎上演進為雙向訊息投遞服務,即不僅支援下行的訊息推送,還支援上行的訊息投遞。Pike 2.0在上行的訊息投遞方面進一步拓展了訊息保序的功能。

這裡的訊息保序主要包含兩個層面的含義:

  • 1)首先每一個業務客戶端傳送的訊息都最大程度地到達同一個業務伺服器;
  • 2)其次這些訊息是按照客戶端傳送的時序一致地到達該業務伺服器。

6.2.1)粘性會話:

為了使每一個業務客戶端傳送的訊息都最大程度地到達同一個業務伺服器,Pike 2.0引入了粘性會話的概念。

粘性會話指的是:同一客戶端連線上的訊息固定轉發至某一特定的業務方機器處理,客戶端斷連重連後,保持新連線上的訊息仍轉發至該業務機器。

粘性會話可以歸納為如下的流程:

  • 1)首次業務登入的時候Pike 2.0伺服器會利用負載均衡演算法選擇一臺業務伺服器,並將該業務伺服器的路由標識通過業務登入結果通知客戶端並儲存,之後如果通道狀態穩定的話所有的上行訊息就都會投遞到該業務伺服器;
  • 2)如果期間通道狀態波動出現斷連的情況,Pike 2.0在發起重連之後會重新進行業務登入,這一次業務登入會將之前儲存的路由標識重新上報給Pike 2.0伺服器,這樣Pike 2.0伺服器就會通過路由標識重新繫結該業務伺服器;
  • 3)如果路由標識指示的業務伺服器已經停止提供服務,那麼Pike 2.0伺服器會重新通過負載均衡演算法選擇新的一臺業務伺服器,同時客戶端會獲取到新的路由標識,之後的邏輯重複該過程直至Pike 2.0客戶端退出。

6.2.2)時序一致性:

我們都知道TCP是有序的,那麼在同一個TCP連線的前提下什麼情況會出現客戶端傳送的訊息亂序到達業務伺服器呢?

原因就是:Pike 2.0伺服器從TCP中讀出訊息之後將其投遞給業務伺服器是通過RPC非同步呼叫的。

為了解決這種問題:最簡單的方案當然是客戶端將訊息佇列的傳送視窗限定為1,每一條傳送訊息都在Pike 2.0伺服器投遞給業務伺服器之後才能收到ACK,這時再發送下一條訊息。但是考慮到網路傳輸在鏈路上的時延遠遠大於端上處理的時延,所以該方案的QPS被網路傳輸設了瓶頸,假設一個RTT是200ms,那麼該方案理論也只能達到5的QPS。

Pike 2.0為了提高上行訊息保序投遞的QPS,採用服務端設定訊息佇列快取的方案。

如下圖所示:客戶端可以在傳送視窗允許的範圍內一次性將多條訊息傳送出去,服務端把收到的訊息都按順序快取在訊息佇列中,然後序列的通過RPC呼叫將這些快取的訊息依序投遞給業務伺服器。

這種保序方案將QPS效能的瓶頸點從之前網路傳輸在鏈路上的時延轉移到了RPC呼叫的時延上,而實際場景中一次RPC呼叫往往在幾個毫秒之間,遠遠小於網路傳輸在鏈路上的時延,繼而顯著地提升了QPS。

訊息時序一致性問題,在實時通訊領域是個很熱門的技術點:

  1. 零基礎IM開發入門(四):什麼是IM系統的訊息時序一致性?
  2. 如何保證IM實時訊息的“時序性”與“一致性”?
  3. 一個低成本確保IM訊息時序的方法探討
  4. 一套億級使用者的IM架構技術乾貨(下篇):可靠性、有序性、弱網優化等

7、v2.0的穩定性保障

7.1 監控體系

Pike 2.0依賴美團監控平臺Raptor完成監控體系建設,服務端和客戶端都建設了各自完善的指標監控。

Pike 2.0客戶端通過利用Raptor的端到端指標能力和自定義指標能力輸出了超過10+個監控指標來實時監控Pike系統,這些指標覆蓋通道建立、訊息投遞、業務登入、系統異常等多維度。

在實時指標監控的基礎上Pike 2.0針對不同指標配置了報警閾值,以推送訊息為例,如果特定App的大盤資料在每分鐘的上下波動幅度超過10%,那麼Raptor系統就會向Pike專案組成員推送告警資訊。

基於所有Raptor監控指標,Pike 2.0提煉核心SLA指標如下:

Pike 2.0會定期輸出基於核心SLA指標的大盤資料報表,同時可以基於App、業務型別、網路型別等多維度對資料進行篩選以滿足不同使用者對於指標資料的需求。

7.2 個案使用者追蹤

監控體系能從全域性的角度反映推送系統穩定性,針對個案使用者,Pike管理平臺提供完整的鏈路追蹤資訊。

每個Pike 2.0連線都由唯一標識Token來區分,通過該唯一標識Token在Pike管理平臺的“連線嗅探”模組主動探測便能獲得對應連線上所有信令的互動流程。

如下圖所示:流程中明確標註了客戶端建立連線、發起鑑權、繫結別名等信令,點選對應信令可以跳轉信令詳情進一步檢視該信令所攜帶的資訊,再結合SDK埋點在美團日誌服務Logan的離線日誌就可以快速發現並定位問題。

8、建設成果

截至2021年6月,Pike共接入業務200+個,日均訊息總量約50億+,Pike 2.0訊息到達率 >99.5%(相比Pike 1.0提升0.4%),Pike 2.0平均端到端延時<220ms(相比Pike 1.0減少約37%)。

部分應用案例:

  • 1)直播場景訊息服務方案:支援直播業務的直播互動功能,具備了支援同時線上百萬級別大型直播的能力;
  • 2)訊息推送、Feed流預載入等實時觸達方案:支援營銷類、控制類等業務訊息實時推送,業務訊息到達率最高提升10%,長連通道建聯耗時減少5%;
  • 3)IoT裝置接入方案:支援取餐櫃業務IoT接入能力,幫助業務訊息到達率從98.4%提升到99.6%;
  • 4)小遊戲場景訊息投遞方案:支援美團小遊戲場景通訊能力,訊息到達率達到99.8%以上,上行延時低至195ms。

9、未來展望

Pike實時訊息推送服務在美團應用廣泛,目前主要集中在實時觸達、互動直播、移動同步等業務場景。隨著公司業務的快速發展,Pike對可用性、易用性、可擴充套件性提出了更高要求,希望提升各種業務場景下的網路體驗。

因此未來Pike的規劃重點主要是:提供多端、多場景下的網路通訊方案,不斷完善協議生態,在各種應用場景下對抗複雜網路。

具體就是:

  • 1)拓展通用基礎能力:提升通道效能。通過優化保序方案,提供專用通道,優化傳輸協議等方式,進一步提升吞吐量和穩定性,降低推送時延;
  • 2)建設物聯網的接入:提供IoT接入層方案。為公司內物聯網應用場景(單車、充電寶、取餐櫃、智慧頭盔、倉庫、門店裝置等)提供統一的IoT接入層解決方案,支援多種接入協議(HTTP、MQTT、CoAP等),為業務提供安全可靠的裝置連線通訊能力;
  • 3)優化弱網通訊體驗:在移動端和IoT端基於美團自研MQUIC網路協議庫,探索Pike over QUIC,在桌面端探索WebTransport技術,通過全面支援QUIC協議,提升弱網大包場景下的網路效能,降低長尾分佈的請求耗時。

附錄:更多實時訊息推送技術文章

  1. iOS的推送服務APNs詳解:設計思路、技術原理及缺陷等
  2. 信鴿團隊原創:一起走過 iOS10 上訊息推送(APNS)的坑
  3. Android端訊息推送總結:實現原理、心跳保活、遇到的問題等
  4. 掃盲貼:認識MQTT通訊協議
  5. 一個基於MQTT通訊協議的完整Android推送Demo
  6. IBM技術經理訪談:MQTT協議的制定歷程、發展現狀等
  7. 求教android訊息推送:GCM、XMPP、MQTT三種方案的優劣
  8. 移動端實時訊息推送技術淺析
  9. 掃盲貼:淺談iOS和Android後臺實時訊息推送的原理和區別
  10. 絕對乾貨:基於Netty實現海量接入的推送服務技術要點
  11. 移動端IM實踐:谷歌訊息推送服務(GCM)研究(來自微信)
  12. 為何微信、QQ這樣的IM工具不使用GCM服務推送訊息?
  13. 極光推送系統大規模高併發架構的技術實踐分享
  14. 從HTTP到MQTT:一個基於位置服務的APP資料通訊實踐概述
  15. 魅族2500萬長連線的實時訊息推送架構的技術實踐分享
  16. 專訪魅族架構師:海量長連線的實時訊息推送系統的心得體會
  17. 深入的聊聊Android訊息推送這件小事
  18. 基於WebSocket實現Hybrid移動應用的訊息推送實踐(含程式碼示例)
  19. 一個基於長連線的安全可擴充套件的訂閱/推送服務實現思路
  20. 實踐分享:如何構建一套高可用的移動端訊息推送系統?
  21. Go語言構建千萬級線上的高併發訊息推送系統實踐(來自360公司)
  22. 騰訊信鴿技術分享:百億級實時訊息推送的實戰經驗
  23. 百萬線上的美拍直播彈幕系統的實時推送技術實踐之路
  24. 京東京麥商家開放平臺的訊息推送架構演進之路
  25. 瞭解iOS訊息推送一文就夠:史上最全iOS Push技術詳解
  26. 基於APNs最新HTTP/2介面實現iOS的高效能訊息推送(服務端篇)
  27. 解密“達達-京東到家”的訂單即時派發技術原理和實踐
  28. 技術乾貨:從零開始,教你設計一個百萬級的訊息推送系統
  29. 長連線閘道器技術專題(四):愛奇藝WebSocket實時推送閘道器技術實踐
  30. 喜馬拉雅億級使用者量的離線訊息推送系統架構設計實踐
  31. 直播系統聊天技術(三):微信直播聊天室單房間1500萬線上的訊息架構演進之路
  32. 直播系統聊天技術(四):百度直播的海量使用者實時訊息系統架構演進實踐
  33. 訊息推送技術乾貨:美團實時訊息推送服務的技術演進之路
  34. >> 更多同類文章 ……

本文已同步釋出於“即時通訊技術圈”公眾號。

▲ 本文在公眾號上的連結是:點此進入。同步釋出連結是:http://www.52im.net/thread-3662-1-1.html

「其他文章」