如何設(shè)計一個幾十萬在線用戶彈幕系統(tǒng)需求方案
1: 需求背景
現(xiàn)在無論是直播還是電視劇,我們都可以看到上面慢慢的彈幕,如果有一天公司自己要做一個這樣的滿足十幾萬用戶在線的彈幕系統(tǒng),我們該如何去設(shè)計呢
2 技術(shù)選型
彈幕跟我們平時做的系統(tǒng)不太一樣,平時做的最多的就是客戶端發(fā)起請求,也就是數(shù)據(jù)都是由客戶端推送到服務(wù)端,但是彈幕是由服務(wù)端推送給客戶端的。比如我們現(xiàn)在在看直播,很多用戶都會發(fā)送彈幕,然后每個在線的用戶都可以收到這條彈幕信息。這時候我們有二種方案
2-1: 客戶端輪訓(xùn)
也就是客戶端不停的去服務(wù)端去拉取數(shù)據(jù),但是會有一個弊端,因為我們每次看電視劇的時候,看一遍一條彈幕只會顯示一次。如果不停的去輪訓(xùn),會有很多無效的請求,而且不停的去輪訓(xùn)無疑會給服務(wù)器造成很大的壓力,因為你客戶端少,如果現(xiàn)在有十幾萬的客戶端同時在線,那么服務(wù)器每隔一段時間就會有幾十萬次的查詢壓力。
2-2: WebSocket主動推送
隨著現(xiàn)在IM系統(tǒng)的成熟,WebSocket也越來越被重視,WebSocket在當(dāng)服務(wù)器收到消息之后,可以主動將消息推送給客戶端。
3: 彈幕初始架構(gòu)
在開始的時候,因為用戶不多,我們只有一臺服務(wù)器,也能滿足需求,但是試想一下,如果某一天用戶增多了,你這一臺服務(wù)器真的頂?shù)米∈畮兹f的用戶來訪問嗎???
既然這時候一臺服務(wù)器壓力太大,那我們就部署多臺服務(wù)器,將壓力進行分攤,這樣每臺服務(wù)器的壓力就不會那么大
但是這時候單臺服務(wù)器壓力是解決了,那推送消息給每一個用戶就做不到了,我們知道WebSocket在推送消息的時候,會先拿到這個用戶的Session,然后通過這個Session將消息推送給這個用戶,但是用戶Session都是保存在我們本地服務(wù)中的。比如這個用戶A的Session在服務(wù)器A上,用戶B在服務(wù)器B上,那么你怎么拿到用戶B的Session呢?
很多人會說,把所有用戶的Session都保存到Redis中不就可以了,其實這樣也不是不行,但是如果你現(xiàn)在有幾百萬,幾千萬的用戶Session呢?
所以我們可以使用消息中間件或者Redis的發(fā)布訂閱模式,比如使用消息中間件RocketMq,有一個用戶發(fā)送了一條彈幕,那么就發(fā)送一條消息到MQ中,所有服務(wù)都接受到這條消息之后,然后就可以拿到本地所有用戶的Session,再進行發(fā)送。
4:彈幕架構(gòu)演進
不知道大家有沒有想過這樣一個問題,假設(shè)我們現(xiàn)在有10臺服務(wù)器,每臺服務(wù)器有一萬人,這時候,一個人發(fā)送一條彈幕,那么每臺服務(wù)器WebSocket都要推送一萬次消息到客戶端,如果這時候有一萬人發(fā)送了彈幕呢?那么WebSocket是不是就要推送 1萬 * 1萬次數(shù)據(jù)呢。在這種高并發(fā)的情況下,WebSocket會因為發(fā)送的太頻繁導(dǎo)致各種各樣的問題,比如與客戶端斷開連接等。
所以第二個難點就在這了
現(xiàn)在我們把所有需要推送的消息都發(fā)送到MQ中,然后在MQ中將消息推送給客戶端。為什么要這么做呢?
在MQ中我們可以進行限流,這樣WebSocket就不用頻繁的去操作了。尤其類似于彈幕這種業(yè)務(wù),也不是說要求實時的。一般我們發(fā)送一條彈幕,都會過個幾秒鐘我們自己才能看見,所以我們可以根據(jù)自己服務(wù)器的性能來決定消費速度。
5:彈幕存儲
用戶發(fā)送的彈幕最終都是要進行持久化存儲的,就像騰訊視頻一樣,無論你什么時候去看,那些彈幕都還在。那么彈幕存儲時機是什么時候呢???
一般都會選擇在用戶發(fā)送一條彈幕之后就存儲這條彈幕,如果用戶發(fā)送一條彈幕我們就同步的將這條數(shù)據(jù)存儲到MySql中,那么這時候有幾十萬的彈幕該怎么辦? 這時候數(shù)據(jù)庫的壓力就很大了。因為彈幕這種數(shù)據(jù)丟個幾條對我們業(yè)務(wù)沒有任何影響,所以我們可以選擇異步存儲,比如將要保存彈幕信息發(fā)送到MQ,MQ異步的將消息存儲到MySql中即可
6:彈幕查詢
對于彈幕查詢,我們后續(xù)可以將數(shù)據(jù)同步到搜索引擎Elasticsearch中,后續(xù)的查詢就直接查ES就好,就不用查數(shù)據(jù)庫,避免對數(shù)據(jù)庫造成壓力。
7:總結(jié)
對于彈幕系統(tǒng)來說,難點就在于二個,
- 第一:對于大量消息推送到客戶端
- 第二:就是消息的異步存儲了
以上就是如何設(shè)計一個幾十萬在線用戶彈幕系統(tǒng)方案的詳細內(nèi)容,更多關(guān)于幾十萬在線用戶彈幕系統(tǒng)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
代碼著色之SyntaxHighlighter項目(最流行的代碼高亮)
dp.SyntaxHighlighter。它可以在網(wǎng)頁中對各種程序源代碼語法進行加亮顯示。支持當(dāng)前流 行的各種編程語言:C#、CSS、C++、Delphi、Java、JavaScript、PHP、Python、Ruby、SQL、Visual Basic、XML / HTML等2014-04-04IDEA使用code?with?me來進行多人遠程編程的實現(xiàn)
本文主要介紹了IDEA使用code?with?me來進行多人遠程編程的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01Elasticsearch?在地理信息空間索引的探索和演進問題分析
本文梳理了Elasticsearch對于數(shù)值索引實現(xiàn)方案的升級和優(yōu)化思考,從2015年至今數(shù)值索引的方案經(jīng)歷了多個版本的迭代,實現(xiàn)思路從最初的字符串模擬到KD-Tree,技術(shù)越來越復(fù)雜,能力越來越強大,應(yīng)用場景也越來越豐富,感興趣的朋友跟隨小編一起看看吧2022-06-06