摘要:愷英網絡程序經理張皓聰在上,做了直播平臺系統實戰的主題分享,介紹了直播平臺系統的搭建過程。張皓聰年加入愷英網絡,先后負責過多款手游頁游項目,對和有深入研究。確保所有的壓力是平均的。
分享 | 張皓聰(愷英網絡程序經理)
整理 | 西北
2016年10月29日,由又拍云舉辦的Open Talk No.26在“魔都”上海3W空間成功舉辦,此次活動主要邀請直播領域開發一線的技術大神們聊一聊直播平臺的架構與優化,看他們化解項目選型、開發上線、迭代過程、性能優化中遇到的挑戰與經驗。
愷英網絡程序經理張皓聰在Open Talk No.26上,做了“直播平臺IM系統實戰”的主題分享,介紹了直播平臺“IM系統”的搭建過程。
張皓聰:2010年加入愷英網絡,先后負責過多款手游頁游項目,對NodeJS和ZeroMQ有深入研究。目前負責愷英網絡“板栗直播”IM系統的相關開發工作。
△ Open Talk No.26現場照片
以下是張皓聰的分享全文
今天我要跟大家分享的是現在非常流行的直播平臺里的“IM系統”。“板栗直播”IM系統從立項初期,到發展致今,已經成為一個功能復雜,擁有一定穩定性的系統。
1.0版本——速度要快我們做IM系統1.0版本時,有以下幾個需求:
一周出 Demo
差不多能用
演示的時候不能突然崩潰
萬一崩潰了不能被發現
性能無所謂
總之,要快速做出來
由于只有一周的時間,第一版的架構搭建得非常簡單:
服務端由 PHP 和 NodeJS 組成。PHP 負責用戶賬戶,注冊和登錄。NodeJS 負責長連以及進出房間和推送,做成簡單的交互。
第一個版本的前端服務器的結構非常簡單,功能很少,僅僅負責聯接客戶端,負責所有客戶端的聯接。為了保證 H5 也可以使用,因此在長連上選擇了WebSocket。
△ IM系統1.0版本架構圖
為了確保客戶端演示的時候,萬一崩潰了也不能被察覺,我們使用 pm2 守護了 node進程。同時讓客戶端同學做了個自動斷線重連。
然后登錄流程是這樣的,先從PHP獲取一個token,然后帶著這個token和node 建立連接,node 會在內網向php驗證 token 是否有效,然后建立連接。
然后廣播方面,使用了我稱作組的形式進行廣播,所有的房間和私信都是通過組的形式進行廣播。
首先,用戶在房間里發言的時候,實際上是往特定組發送廣播。組的名字是用特定字符開頭來歸類的。
舉例來說,需要向10000房間發送聊天信息時,實際上是向 r:10000 這個組發送信息。此時服務端會遍歷該組里所有連接,并發送消息。
當需要進行全服廣播的時候,我們使用一個寫死特殊的 0 號房間,轉換成 gid 也就是 r:0 發送消息。這將遍歷所有連接,向他們發送消息。
接下來是推送私聊,這里我為每個用戶都設置了一個私有的 gid,這樣發送私信的時候也相當于發送了廣播,服務端可以用相同邏輯處理。打個比方向 uid 20000 用戶發送私信,相當于向 u:20000 廣播。以后擴展成多進程多主機模式時,也不必知道這個用戶目前在哪臺服務器上,推送私信就會很方便。
在這個設計中,一位用戶是允許加入多個組的。就像群聊一樣,一開始就使用這樣的設計,以后可以很容易的進行擴展。
由于采用了單點連接的形式,并不需要每次進房間都建立新連接,客戶端只要首次進行連接,之后發送請求就可以進出房間,也節省了客戶端的開發工作。
2.0版本需求:
內測版本
支持擴容
更高的可用性
禮物信息比聊天優先級高
特定消息要發送回執
當1.0版本完成之后,接下來就是要開發 2.0 版本。
這個版本里增加了一些必要的需求。
首先,這是一個內測版本。在內測版本中會邀請用戶使用,并進行測試。
期間可能由于用戶數增多,也可能因為我們代碼本身的原因或是 bug 造成服務器壓力增加,此時會有擴容方面的需求。
第二個是要增加廣播優先級的功能,這個很簡單,禮物肯定是比普通信息優先級更高的。
最后是特定消息的回執發送,這個我們目前也還沒有實現,但是需求一直是在的。
△ IM系統2.0版本的架構
上圖中可以看到模塊數增加了,但是總的來說客戶端需求并沒有變化,基本流程的連接流程仍然是先問 PHP 要 token,再去連接 WS。由于我們允許把 WS 部署在多個主機上,在這中間增加了一步就是訪問 LB 獲得 WS 地址。LB 會輪詢的告知客戶端本次應使用哪個 WS,并把 IP 返回給客戶端。確保所有 WS 的壓力是平均的。
另外還有一處增加的功能是,由于 WS 已經分離到多個進程了,那么需要一個地方可以用來處理廣播。這邊我們選擇了 redis 的進行廣播。
同時另外還部署了一臺 redis 是專門用來保存在線列表等數據。
△ 帶有優先級的推送消息
上圖是一個帶有優先級的推送消息。
大家可注意到,我們為每個組的gid增加了一個后綴,這個后綴是用來區分優先級的。
比如說用戶進入房間 10000,那么我會把他放到 2 個組,分別是 r:10000._ 和 r:10000.n。
同時 node 也會向 redis 訂閱兩個同名頻道,此時服務端就可以從 2 個頻道收到推送消息,分別是 _(普通) 和 n (優先)。
后端會有聊天信息要推送,會根據優先級,是使用普通頻道還是優先頻道進行廣播。
node 這邊會開一個主循環,比如設置 12fps ,每一幀會優先轉發優先組(頻道)中的消息,然后才是普通消息,根據當時壓力,將會選擇拋棄普通消息。
3.0版本需求:
業務邏輯越來越多,需要拆分
需要支持熱更
更好的廣播性能
優化與其他服務的通信
日志系統
部署腳本
到了3.0版本時,需求越來越多,需要拆分。
線上有時候會有bug和做活動,會有熱更的需求。
redis 廣播有可能出現瓶頸,在這之前需要需要更好的廣播性能。
同時還需要優化與其他服務器之間的通信。
最后還需要需要有一個簡單的日志搜集器。
△ IM系統3.0版本架構
這是3.0版本的架構。大家可以看到下面有大量的服務了。其實這些服務原來是在WebSocket里面的,現在把它拆成不同的進程。
客戶端連接這塊沒有變化,客戶端仍然需要問 PHP 要 token,問 LB 要地址,最后再連接。
這個版本的 WS 功能上更加單一,只負責消息轉發。
在這個版本里,我們做了一套 RPC 框架,用來方便調用內網各服務的接口。
增加了日志搜集器和API的服務。以及IM系統(私聊)。用戶之間可以聊天和查看聊天記錄等。
總的來說,功能上沒有特別大的變化,尤其是接口方面是向前兼容的。
△ 通過RPC中轉的推送消息
下面我介紹一下RPC服務框架。
我們的 RPC 框架是基于 ZeroMQ 的。利用他的里的Dealer和Router 進行消息的收發。
ZeroMQ 自帶自動重連和負載均衡功能,這方面也不用太操心,節省了開發時間。
數據交換格式是JSON,明文傳輸,調試也會很方便。
ZeroMQ 性能
-E5-2630,8G 內存,千兆網卡的測試結果
#local_thr tcp://*:5555 100 10000000
message size: 100 [B]
message count: 10000000
mean throughput: 1097051 [msg/s]
mean throughput: 877.641 [Mb/s]
還有就是我們不再使用 redis 做廣播,而改用 ZeroMQ 的 pub 和 sub 做廣播服務。這樣廣播性能就有了很大提升。
4.0版本——更高要求IM系統4.0版本的需求
廣播和業務分離
優化PRC協議
針對個別地區進行網絡優化
到了這個階段,我們遇到了一些個別地區網絡較慢的問題。
我們把 WS 和 LB 放到了代理服務器后面。LB 可以根據不同運營商用戶,返回代理了的 WS 地址。
△ RPC服務路由
同時還優化了RPC 服務,我們為 RPC 服務增加了路由器,所有的 Worker 都隱藏在他后面,這樣客戶端調用的時候并不需要知道具體 Worker 的地址。Worker 的更新重啟也不會影響其他客戶端。
廣播服務也得到了業務和廣播分離,同時集群化。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/11760.html
閱讀 2250·2021-11-16 11:44
閱讀 644·2019-08-30 15:55
閱讀 3277·2019-08-30 15:52
閱讀 3614·2019-08-30 15:43
閱讀 2201·2019-08-30 11:21
閱讀 439·2019-08-29 12:18
閱讀 1951·2019-08-26 18:15
閱讀 473·2019-08-26 10:32