成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

彈幕系統更新的血與淚

移動開發
16年是直播浪潮興起的元年,許多互聯網公司的業務都開始涉足直播內容模塊。我目前所在公司接手的第一份工作,就是直播業務中的彈幕系統優化。隨著公司直播業務的變化,彈幕系統從最初的版本到后來優化了三四個版本,這個過程大概持續了一年的時間,本文將從我司早期的彈幕系統開始給大家介紹整個更新過程的“血與淚 ”。

16年是直播浪潮興起的元年,許多互聯網公司的業務都開始涉足直播內容模塊。我目前所在公司接手的***份工作,就是直播業務中的彈幕系統優化。隨著公司直播業務的變化,彈幕系統從最初的版本到后來優化了三四個版本,這個過程大概持續了一年的時間,本文將從我司早期的彈幕系統開始給大家介紹整個更新過程的“血與淚 ”。

早期彈幕系統

一、基本狀況

  1. 由PHP + Gateway框架編寫
  2. 所有的Client ID存放在Redis里面
  3. 最初由三臺機器掛載在LVS系統后方提供服務
  4. 使用多進程的方式,開啟多個worker進程來處理消息傳遞內容

二、存在的問題

  1. 內存占用量巨大,單機(4核8G配置)承受500左右的Client就會達到內存上限
  2. 每次發送消息的時候,每臺機器都需要從Redis里面拿取對應房間的所有Client ID;并發高時,Redis的單進程處理效率和內網帶寬就成為瓶頸 。
  3. 單機的并發處理能力被消息處理的worker進程數量限制。同時開啟過多的進程,也是對系統資源的格外浪費。
  4. 單房間超過2000人的時候,消息的延遲有可能會達到1分鐘左右,這是極其嚴重的問題。

三、臨時改造

由于需要解決的問題比較緊迫,所以快速做了一些邏輯上的改變和業務層面的取舍:

  1. 對Redis的實例進行了拆分,使用了雙機,單機4實例的方式,分散了Redis的壓力
  2. 對消息處理worker進程的邏輯做了一些修改,限制了單位時間內進行廣播的消息數量,多余的消息會被丟棄 。
  3. 對于已經完成了直播進入點播狀態的房間,額外啟用了另外一套彈幕系統來進行分流。
  4. 單個房間切成多個房間進行消息處理。

四、改造之后的效果

  1. Redis壓力大幅度降低
  2. 單機IO性能壓力降低
  3. 同樣數量的機器,可以承載更多的直播房間個數

[[214239]]

但是,根本問題并沒有得到解決。在臨時解決壓力問題之后,我們需要花一些時間來重新對彈幕系統進行分析,按照分析后的需求,對新的彈幕系統進行重構。

新的彈幕系統

一、新彈幕系統面臨的挑戰

  1. 單房間人數較高,依照我們公司直播情況,單房間5 – 10萬人同時在線是會出現的。
  2. 由于直播內容等情況造成的某時間段用戶暴漲。
  3. 需要盡可能實時到達,延遲過高的話會大大降低互動的實時性。
  4. 每一條消息,都要遞送大量的長連接。
  5. 大量長連接的維護機制。
  6. 在運營的過程中,需要處理用戶黑名單、IP黑名單、敏感詞等需求。

二、新的彈幕系統需求

  1. 由于內存的管理對于PHP來說算是一個短板,對于大并發且長時間穩定不需要經常更新維護的系統來說,并非***的選擇,因此選一門合適的語言是必須的。
  2. 分布式支持,可以快速的橫向擴展,單房間人數可以支持到十萬級別。
  3. 可以方便快捷的對系統進行第三方消息的發送(例如禮物信息、系統通知等)。
  4. 盡量使用本地內存管理來記錄房間內客戶端連接,剩下大量的數據交互和查詢時間。
  5. 并發支持消息廣播,提高廣播效率。

三、新彈幕系統版本的改造方法

  1. 選擇當前正紅且對高并發支持良好的Golang作為開發語言。
  2. 使用開發語言進行客戶端連接的管理,且每臺機器只管理自己收到的連接請求。
  3. 使用并發的房間內廣播邏輯,同時對多人進行廣播。

新彈幕系統改造的相關經驗

下面先對一個模塊細節進行分析,然后進一步分析模塊上層的調度邏輯。

一、房間管理

 

  1. type RoomInfo struct {  
  2. RoomID string //房間ID  
  3. Lock *sync.Mutex //房間操作鎖  
  4. Rows []*RowList //房間多行Slice  
  5. Length uint64 //當前房間總節點數  
  6. LastChangeTime time.Time //***一次更新時間  
  7.  
  8. type RowList struct {  
  9. Nodes []*Node //節點列表  

由于每個房間都有自己的ID,客戶端建立連接之后,就會被放到一個大廳房間里面。接著,客戶端自己提交RoomID上來,連接會被重新連接到對應的房間里面。 每個連接在建立之后,都會被包裝成一個Node,放到Rows里面。

 

  1. type Node struct {  
  2. RoomID       string  
  3. ClientID     int64  
  4. Conn         *websocket.Conn  
  5. UpdateTime   time.Time  
  6. LastSendTime time.Time //***一次發送消息時間  
  7. IsAlive      bool  
  8. DisabledRead    bool//是否已經被關閉了發言權限  

每一個Node中,都有一個IsAlive來表示連接是否成功。如果連接斷開,或者因為其他原因強制停止服務的話,會修改此標記狀態。然后由定時的處理機制將此連接關閉并從內存中清除。 Rows的本質就是一組事先設定了長度的Node Slice。

發送消息的時候,每一組slice使用一個協程來順序發送。同一房間內的連接,就可以依照slice分組進行并發發送。 發送的時候,會使用鎖將整個房間鎖住,以防止并發情況下同一連接混入兩條信息。

二、消息管理

 

  1. var messageChannel map[string]chan nodeMessage  
  2. func init() {  
  3. messageChannel = make(map[string]chan nodeMessage)  
  4.  
  5. func sendMessageToChannel(roomId string, nm nodeMessage) error {  
  6. //如果房間不存在,創建一個房間  
  7. if c, ok := messageChannel[roomId]; ok {  
  8.  
  9. else {  
  10. //創建房間通道  
  11. messageChannel[roomId] = make(chan nodeMessage, 1024)  
  12. messageChannel[roomId]  
  13. //創建房間實例  
  14. roomObj := &RoomInfo{}  
  15. roomObj.RoomID = roomId  
  16. roomObj.Rows = make([]*RowList, 0, 4)  
  17. roomObj.Lock = &sync.Mutex{}  
  18. //創建新的協程來監控房間  
  19. go daemonReciver(messageChannel[roomId], roomObj)  
  20. go timerForClean(messageChannel[roomId])  
  21. //如果是大廳的話,啟動大廳清理協程  
  22. if roomId == "" {  
  23. go CleanHall(roomObj)  
  24.  
  25.  
  26. return nil  

以上是關于彈幕信息傳遞的一部分代碼。 首先,每一個房間,都有自己的消息通道,所有的這些通道根據RoomID為key,記錄在一個叫做messageChannel的map里面。 每次收到消息的時候,都直接把消息丟到channel里面,就可以了。(后面由守護協程來處理)如果沒有房間通道的話,就建立房間的通道channel,并啟動每個房間的一系列協程。

三、服務器管理

這里的方案比較簡單,其實就是建立一個上一層的聊天室即一個房間,所有的服務器都會主動連接到這里,每一個服務器收到的信息,就會在這個房間里面廣播到別的機器去。

四、守護協程們管理

守護協程處理很多瑣碎的事情,保證房間內信息的正常分發以及房間連接的正常管理。各個守護協程的功能如下:

  1. 消息發送協程:每個房間配備一個,從channel里面獲取到要發送到本房間的消息,然后在并發調用各個RowList的發送消息機制。
  2. 房間整理協程 :因為會有連接斷開、房間更換等修改Node狀態的行為,所以定期會有房間整理協程來進行節點整理,刪除當前房間無關的節點等以提高消息的發送效率。

[[214240]]

五、測試相關

  • 運行環境:云主機8核16G實例
  • 操作系統:Centos7(未進行系統優化或參數調整)
  • 測試內容:單機建立15000 websocket連接,并且發送消息,進入指定房間(所有連接進入同一房間)。一個客戶端進入房間,發送一條消息,經過敏感詞處理、IP和用戶黑名單處理,然后被廣播到所有節點。

測試結果:

  • CPU占用:保持在5%以下
  • 內存占用:2GB(包括操作系統本身開銷)
  • 網絡占用:峰值10Mb/s左右
  • 發送效率:15000節點廣播,100ms – 110ms左右。

根據測試結果計算:

完全可以在8核16G的機器上,實現無壓力運行50K并發,峰值接近60 – 70K的處理能力。

六、更多分享

我目前正在嘗試把完成這套彈幕系統的基本功能開源出來。已經提取出來了一部分,當前的地址為:https://github.com/logan-go/roomManager,感興趣的讀者可以通過鏈接查看。

小結

彈幕系統給視頻直播/點播增加了更多內容的互動娛樂性質,從最初的A站B站發展到現在各主流視頻網站APP。如何健康高效的管理彈幕系統,也是當下視頻行業需要重視的一門技術活。

責任編輯:未麗燕 來源: U刻
相關推薦

2017-12-20 12:32:26

彈幕系統更新

2014-08-01 14:32:29

創業90后創業

2018-04-11 15:42:04

開源項目姿勢

2012-12-24 09:18:22

iOSUnity3D

2017-05-11 22:43:53

2025-06-16 04:00:00

Spring彈幕技術

2025-06-16 01:00:00

彈幕系統架構

2015-07-16 12:37:28

彈幕

2011-01-14 16:51:44

Linux內核

2019-01-02 16:38:37

Golang彈幕

2019-01-02 16:47:46

Golang彈幕

2019-01-02 16:50:30

Golang彈幕

2019-11-20 18:47:26

物聯網OTA軟件

2010-04-28 15:38:54

2021-06-22 18:28:58

程序員技能開發者

2023-01-04 09:29:03

線程業務代碼

2010-12-23 14:17:14

Web 2.0

2018-05-08 09:00:00

系統更新

2019-03-29 09:01:39

彈幕微博Python
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲国产精品99久久久久久久久 | 99精品欧美一区二区蜜桃免费 | 欧美精品一二区 | 亚洲成人午夜在线 | 日韩一级一区 | 日韩a在线 | 欧美精品一区二区在线观看 | 国产精品久久久久久吹潮 | 天堂视频一区 | 夜久久 | 精品久久网| 羞羞视频免费观 | 尤物在线视频 | 韩国av一区二区 | 午夜av一区二区 | 澳门永久av免费网站 | 亚洲精品亚洲人成人网 | 操皮视频| 91中文 | 99久久精品免费看国产高清 | 国产亚洲精品成人av久久ww | 久久久青草婷婷精品综合日韩 | 精品一区久久 | 亚洲黄色av| 久久精品亚洲国产奇米99 | 另类 综合 日韩 欧美 亚洲 | 日韩欧美精品在线 | 免费一级欧美在线观看视频 | 久久精品一级 | 黄色一级电影在线观看 | caoporn国产精品免费公开 | 完全免费在线视频 | 久久99精品久久久久久秒播九色 | 成人激情视频免费在线观看 | 亚洲成人免费 | 色综合久久久久 | 国产精品一区二区免费 | 国产一区在线免费观看视频 | 中文字幕亚洲一区 | 亚洲一区中文字幕在线观看 | 波多野结衣一区二区三区 |