長連線閘道器技術專題(四):愛奇藝WebSocket實時推送閘道器技術實踐

語言: CN / TW / HK

本文由愛奇藝技術團隊原創分享,原題《構建通用WebSocket推送閘道器的設計與實踐》,有優化和改動。

1、引言

叢所周之,HTTP協議是一種無狀態、基於TCP的請求/響應模式的協議,即請求只能由客戶端發起、由服務端進行響應。在大多數場景,這種請求/響應的Pull模式可以滿足需求。但在某些情形:例如訊息推送(IM中最為常見,比如IM的離線訊息推送)、實時通知等應用場景,需要實時將資料同步到客戶端,這就要求服務端支援主動Push資料的能力。

傳統的Web服務端推送技術歷史悠久,經歷了短輪詢、長輪詢等階段的發展(見《新手入門貼:史上最全Web端即時通訊技術原理詳解》),一定程度上能夠解決問題,但也存在著不足,例如時效性、資源浪費等。HTML5標準帶來的WebSocket規範基本結束了這一局面,成為目前服務端訊息推送技術的主流方案。

在系統中整合WebSocket十分簡單,相關討論與資料很豐富。但如何實現一個通用的WebSocket推送閘道器尚未有成熟的方案。目前的雲服務廠商主要關注iOS和安卓等移動端推送,也缺少對WebSocket的支援。本文分享了愛奇藝基於Netty實現WebSocket長連線實時推送閘道器時的實踐經驗總結。

2、專題目錄

本文是系列文章的第4篇,總目錄如下:

長連線閘道器技術專題(一):京東京麥的生產級TCP閘道器技術實踐總結

長連線閘道器技術專題(二):知乎千萬級併發的高效能長連線閘道器技術實踐

長連線閘道器技術專題(三):手淘億級移動端接入層閘道器的技術演進之路

長連線閘道器技術專題(四):愛奇藝WebSocket實時推送閘道器技術實踐》(* 本文)

其它相關技術文章:

絕對乾貨:基於Netty實現海量接入的推送服務技術要點

京東到家基於Netty的WebSocket應用實踐分享

愛奇藝技術團隊分享的其它文章:

愛奇藝技術分享:輕鬆詼諧,講解視訊編解碼技術的過去、現在和將來

愛奇藝技術分享:愛奇藝Android客戶端啟動速度優化實踐總結

愛奇藝移動端網路優化實踐分享:網路請求成功率優化篇

3、舊方案存在的技術痛點

愛奇藝號是我們內容生態的重要組成,作為前臺系統,對使用者體驗有較高要求,直接影響著創作者的創作熱情。

目前,愛奇藝號多個業務場景中用到了WebSocket實時推送技術,包括:

  • 1)使用者評論:實時的將評論訊息推送到瀏覽器;
  • 2)實名認證:合同簽署前需要對使用者進行實名認證,使用者掃描二維碼後進入第三方的認證頁面,認證完成後非同步通知瀏覽器認證的狀態;
  • 3)活體識別:類似實名認證,當活體識別完成後,非同步將結果通知瀏覽器。

在實際的業務開發中,我們發現,WebSocket實時推送技術在使用中存在一些問題。

這些問題是:

  • 1)首先:WebSocket技術棧不統一,既有基於Netty實現的,也有基於Web容器實現的,給開發和維護帶來困難;
  • 2)其次:WebSocket實現分散在在各個工程中,與業務系統強耦合,如果有其他業務需要整合WebSocket,面臨著重複開發的窘境,浪費成本、效率低下;
  • 3)第三:WebSocket是有狀態協議的,客戶端連線伺服器時只和叢集中一個節點連線,資料傳輸過程中也只與這一節點通訊。WebSocket叢集需要解決會話共享的問題。如果只採用單節點部署,雖然可以避免這一問題,但無法水平擴充套件支撐更高負載,有單點的風險;
  • 4)最後:缺乏監控與報警,雖然可以通過Linux的Socket連線數大致評估WebSocket長連線數,但數字並不準確,也無法得知使用者數等具有業務含義的指標資料;無法與現有的微服務監控整合,實現統一監控和報警。

PS:限於篇幅本文不詳細介紹WebSocket技術本身,有興趣可以詳讀《WebSocket從入門到精通,半小時就夠!》。

4、新方案的技術目標

如上節所示,為了解決舊方案中存在的問題,我們需要實現統一的WebSocket長連線實時推送閘道器。

這套新的閘道器需要具備如下特點:

  • 1)集中實現長連線管理和推送能力:統一技術棧,將長連線作為基礎能力沉澱,便於功能迭代和升級維護;
  • 2)與業務解耦:將業務邏輯與長連線通訊分離,使業務系統不再關心通訊細節,也避免了重複開發,浪費研發成本;
  • 3)使用簡單:提供HTTP推送通道,方便各種開發語言的接入。業務系統只需要簡單的呼叫,就可以實現資料推送,提升研發效率;
  • 4)分散式架構:實現多節點的叢集,支援水平擴充套件應對業務增長帶來的挑戰;節點宕機不影響服務整體可用性,保證高可靠;
  • 5)多端訊息同步:允許使用者使用多個瀏覽器或標籤頁同時登陸線上,保證訊息同步傳送;
  • 6)多維度監控與報警:自定義監控指標與現有微服務監控系統打通,出現問題時可及時報警,保證服務的穩定性。

5、新方案的技術選型

在眾多的WebSocket實現中,從效能、擴充套件性、社群支援等方面考慮,最終選擇了Netty。Netty是一個高效能、事件驅動、非同步非阻塞的網路通訊框架,在許多知名的開源軟體中被廣泛使用。

PS:如果你對Netty知之甚少,可以詳讀以下兩篇:

WebSocket是有狀態的,無法像直接HTTP以叢集方式實現負載均衡,長連線建立後即與服務端某個節點保持著會話,因此叢集下想要得知會話屬於哪個節點有點困難。

解決以上問題一般有兩種技術方案:

  • 1)一種是使用類似微服務的註冊中心來維護全域性的會話對映關係;
  • 2)一種是使用事件廣播由各節點自行判斷是否持有會話,兩種方案對比如下表所示。

WebSocket叢集方案:

綜合考慮實現成本與叢集規模,選擇了輕量級的事件廣播方案。

實現廣播可以選擇基於RocketMQ的訊息廣播、基於Redis的Publish/Subscribe、基於ZooKeeper的通知等方案,其優缺點對比如下表所示。從吞吐量、實時性、持久化、實現難易等方面考慮,最終選擇了RocketMQ。

廣播的實現方案對比:

6、新方案的實現思路

6.1 系統架構

閘道器的整體架構如下圖所示:

閘道器的整體流程如下:

1)客戶端與閘道器任一節點握手建立起長連線,節點將其加入到記憶體維護的長連線佇列。客戶端定時向服務端傳送心跳訊息,如果超過設定的時間仍沒有收到心跳,則認為客戶端與服務端的長連線已斷開,服務端會關閉連線,清理記憶體中的會話。

2)當業務系統需要向客戶端推送資料時,通過閘道器提供的HTTP介面將資料發向閘道器。

3)閘道器在接收到推送請求後,將訊息寫入RocketMQ。

4)閘道器作為消費者,以廣播模式消費訊息,所有節點都會接收到訊息。

5)節點接收到訊息後判斷推送的訊息目標是否在自己記憶體中維護的長連線佇列裡,如果存在則通過長連線推送資料,否則直接忽略。

閘道器以多節點方式構成叢集,每節點負責一部分長連線,可實現負載均衡,當面對海量連線時,也可以通過增加節點的方式分擔壓力,實現水平擴充套件。

同時,當節點出現宕機時,客戶端會嘗試重新與其他節點握手建立長連線,保證服務整體的可用性。

6.2 會話管理

WebSocket長連線建立起來後,會話維護在各節點的記憶體中。SessionManager元件負責管理會話,內部使用了雜湊表維護了UID與UserSession的關係。

UserSession代表使用者維度的會話,一個使用者可能會同時建立多個長連線,因此UserSession內部同樣使用了一個雜湊表維護Channel與ChannelSession的關係。

為了避免使用者無限制的建立長連線,UserSession在內部的ChannelSession超過一定數量後,會將最早建立的ChannelSession關閉,減少伺服器資源佔用。SessionManager、UserSession、ChannelSession的關係如下圖所示。

SessionManager元件:

6.3 監控與報警

為了瞭解叢集建立了多少長連線、包含了多少使用者,閘道器提供了基本的監控與報警能力。

閘道器接入了Micrometer,將連線數與使用者數作為自定義指標暴露,供Prometheus進行採集,實現了與現有的微服務監控系統打通。

Grafana中方便地檢視連線數、使用者數、JVM、CPU、記憶體等指標資料,瞭解閘道器當前的服務能力與壓力。報警規則也可以在Grafana中配置,當資料異常時觸發奇信(內部報警平臺)報警。

7、新方案的效能壓測

壓測準備:

  • 1)壓測選擇兩臺配置為4核16G的虛擬機器,分別作為伺服器和客戶端;
  • 2)壓測時選擇為閘道器開放了20個埠,同時建立20個客戶端;
  • 3)每個客戶端使用一個服務端埠建立起5萬連線,可以同時建立百萬個連線。

連線數(百萬級)與記憶體使用情況如下圖所示:

給百萬個長連線同時傳送一條訊息,採用單執行緒傳送,伺服器傳送完成的平均耗時在10s左右,如下圖所示。

伺服器推送耗時: 

一般同一使用者同時建立的長連線都在個位數。以10個長連線為例,在併發數600、持續時間120s條件下壓測,推送介面的TPS大約在1600+,如下圖所示。

長連線10、併發600、持續時間120s的壓測資料:

當前的效能指標已滿足我們的實際業務場景,可支援未來的業務增長。

8、新方案的實際應用案例

為了更生動的說明優化效果,文章最後,我們也以封面圖新增濾鏡效果為例,介紹一個愛奇藝號使用新WebSocket閘道器方案的案例。

愛奇藝號自媒體發表視訊時,可選擇為封面圖新增濾鏡效果,引導使用者提供提供更優質的封面。

當用戶選擇一個封面圖後,會提交非同步的後臺處理任務。當非同步任務處理完成後,通過WebSocket將不同濾鏡效果處理後的圖片返回給瀏覽器,業務場景如下圖所示。

從研發效率方面考慮,如果在業務系統中整合WebSocket,至少需要1-2天的開發時間。

如果直接使用新的WebSocket閘道器的推送能力,只需要簡單的介面呼叫就實現了資料推送,開發時間降低到分鐘級別,研發效率大大提高。

從運維成本方面考慮,業務系統不再含有與業務邏輯無關的通訊細節,程式碼的可維護性更強,系統架構變得更加簡單,運維成本大大降低。

9、寫在最後

WebSocket是目前實現服務端推送的主流技術,恰當使用能夠有效提供系統響應能力,提升使用者體驗。通過WebSocket長連線閘道器可以快速為系統增加資料推送能力,有效減少運維成本,提高開發效率。

長連線閘道器的價值在於:

  • 1)它封裝了WebSocket通訊細節,與業務系統解耦,使得長連線閘道器與業務系統可獨立優化迭代,避免重複開發,便於開發與維護;
  • 2)閘道器提供了簡單易用的HTTP推送通道,支援多種開發語言接入,便於系統整合和使用;
  • 3)閘道器採用了分散式架構,可以實現服務的水平擴容、負載均衡與高可用;
  • 4)閘道器集成了監控與報警,當系統異常時能及時預警,保證服務的健康和穩定。

目前,新的WebSocket長連線實時閘道器已在愛奇藝號圖片濾鏡結果通知、MCN電子簽章等多個業務場景中得到應用。

未來還有許多方面需要探索,例如訊息的重發與ACK、WebSocket二進位制資料的支援、多租戶的支援等。

附錄:更多相關技術資料

[1] 有關WEB端即時通訊開發:

新手入門貼:史上最全Web端即時通訊技術原理詳解

Web端即時通訊技術盤點:短輪詢、Comet、Websocket、SSE

SSE技術詳解:一種全新的HTML5伺服器推送事件技術

Comet技術詳解:基於HTTP長連線的Web端實時通訊技術

新手快速入門:WebSocket簡明教程

WebSocket詳解(一):初步認識WebSocket技術

WebSocket詳解(二):技術原理、程式碼演示和應用案例

WebSocket詳解(三):深入WebSocket通訊協議細節

WebSocket詳解(四):刨根問底HTTP與WebSocket的關係(上篇)

WebSocket詳解(五):刨根問底HTTP與WebSocket的關係(下篇)

WebSocket詳解(六):刨根問底WebSocket與Socket的關係

socket.io實現訊息推送的一點實踐及思路

LinkedIn的Web端即時通訊實踐:實現單機幾十萬條長連線

Web端即時通訊技術的發展與WebSocket、Socket.io的技術實踐

Web端即時通訊安全:跨站點WebSocket劫持漏洞詳解(含示例程式碼)

開源框架Pomelo實踐:搭建Web端高效能分散式IM聊天伺服器

使用WebSocket和SSE技術實現Web端訊息推送

詳解Web端通訊方式的演進:從Ajax、JSONP 到 SSE、Websocket

MobileIMSDK-Web的網路層框架為何使用的是Socket.io而不是Netty?

理論聯絡實際:從零理解WebSocket的通訊原理、協議格式、安全性

微信小程式中如何使用WebSocket實現長連線(含完整原始碼)

八問WebSocket協議:為你快速解答WebSocket熱門疑問

Web端即時通訊實踐乾貨:如何讓你的WebSocket斷網重連更快速?

WebSocket從入門到精通,半小時就夠!

WebSocket硬核入門:200行程式碼,教你徒手擼一個WebSocket伺服器

>> 更多同類文章 ……

[2] 有關推送技術的文章:

一個基於MQTT通訊協議的完整Android推送Demo

求教android訊息推送:GCM、XMPP、MQTT三種方案的優劣

移動端實時訊息推送技術淺析

絕對乾貨:基於Netty實現海量接入的推送服務技術要點

極光推送系統大規模高併發架構的技術實踐分享

魅族2500萬長連線的實時訊息推送架構的技術實踐分享

專訪魅族架構師:海量長連線的實時訊息推送系統的心得體會

基於WebSocket實現Hybrid移動應用的訊息推送實踐(含程式碼示例)

一個基於長連線的安全可擴充套件的訂閱/推送服務實現思路

實踐分享:如何構建一套高可用的移動端訊息推送系統?

Go語言構建千萬級線上的高併發訊息推送系統實踐(來自360公司)

騰訊信鴿技術分享:百億級實時訊息推送的實戰經驗

百萬線上的美拍直播彈幕系統的實時推送技術實踐之路

京東京麥商家開放平臺的訊息推送架構演進之路

技術乾貨:從零開始,教你設計一個百萬級的訊息推送系統

長連線閘道器技術專題(四):愛奇藝WebSocket實時推送閘道器技術實踐

>> 更多同類文章 ……

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

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

「其他文章」