遊戲伺服器全服廣播消息正確的做法?

一般看別人大多都是遍歷在線玩家直接發消息,但我不知道人數多的情況會不會有問題,然後我寫了一個隊列保存全服的廣播信息,每個玩家定時去取廣播,我覺得這樣比遍歷所有在線玩家並同時發送廣播要好,然而今天給主程斃了,說直接遍歷就好。請高人指點一下,我該如何評判哪種方案合適呢


顯然定時取是不可取的,遊戲本身如果廣播消息不多,客戶端去定時取會白白增加很多無用的消息包。

其次,還要維護這個消息緩存的大小,考慮到客戶端拉取時機不定,這個消息緩存的消息的生命期要大於客戶端拉取的時間間隔以給與一定容錯空間,並且要給每個消息打上時間戳。客戶端請求上來後要根據上次時間戳做過濾,這樣設計上變得很複雜,性能上也未必好很多。

所以遍歷發消息應該是最為簡單可靠的,如果認為性能不好,就把玩家分配到若干個聊天服上,那麼整個流程是:

某服務發起廣播消息 -&> 消息發送到路由/中轉服務 -&> 廣播到所有聊天服 -&> 各個聊天服廣播消息(遍歷發送)到自己管理的所有玩家上


基本上是借鑒MQ的觀察者模式(訂閱-通知)。

客戶端阻塞讀,服務端廣播到每個客戶端消息隊列。MQ可以主動將消息推送到客戶端。

如果說客戶端太多,比如要把消息廣播到上萬個客戶端隊列,可以多線程並發寫入。

activeMq或RabbitMq都有訂閱和通知介面直接調用。


全服廣播這樣的功能需要一個先決條件,那就是能夠訪問到玩家的session,並且發送時無需複雜的消息處理。

這種功能一般可以由聊天伺服器代理,因為一般情況下玩家都會被加入到聊天系統中。另外,這種全局廣播功能也會和GM後台對接,可以讓運營人員在GM後台直接發送全局廣播,所以經常的設計是伺服器各個系統統一把廣播消息發送到聊天伺服器上,再由聊天伺服器轉發給各個網關進行實際的發送。

對於特別的,比如家族內廣播,也很好辦,一般會有「家族聊天頻道」這樣的設計,所以聊天伺服器也會知道家族中包含哪些人,同理還有小隊廣播等。

以上就是全局廣播這類功能經常的實現方法。

如果你能理解,那麼你就會發現定時獲取全局廣播是一件比較難理解的事情。


客戶端定時取肯定是不可取的,需要先處理客戶端請求再發送消息,相比伺服器直接推送消息多了一倍開銷,如果沒廣播消息的話更是空耗伺服器資源。

當然,如果廣播消息需要遊戲邏輯去遍歷所有玩家的話,說明你們的伺服器框架還非常簡陋。像廣播、多播這樣的操作框架層應該提供統一的介面,交給框架來處理。如果是單伺服器架構的話內部當然也是去遍歷,而分散式框架的話則可以轉發給前端代理去進行遍歷發送。上層的邏輯程序員不應該去關心這些實現細節,這樣也就不會出現題主的那些糾結了。


對比性能,很明顯你的主動拉pull的過程更消耗資源。存儲廣播消息,浪費內存,管理廣播消息,每個消息肯定都有生命周期吧,浪費cpu。玩家主動pull,有一次請求過程,浪費帶寬。如果你覺得每條小的全服廣播過於消耗性能,可以做一個類似拼包的延遲發送,只是客戶端上體驗略有延遲,原理同tcp的delay演算法。


遍歷完扔隊列裡面,再讓知曉負載情況的進程或者服務搞吧,估計你們的框架就是這麼實現的,畢竟框架的目的就是讓日常代碼關注普通邏輯。

每個玩家取的做法肯定要打槍的。消息量翻好多倍了。

謝邀


08年,登錄了之前的夢幻西遊,收到了04年最後一次下線未閱讀的好友信息。

我想應該是賬號登錄後,取回所有信息。根據信息狀態提示是否有新信息的。


你的主程是對的。

其他先不說,你這個定時讀,定多久的時?和輪詢一樣嗎?我先不說它造成的無意義查詢浪費資源,你連最基本的廣播的時效性都不好保證,你定半個小時查一次還是一個小時查一次?所有客戶端同時都定半個小時還是分組去?如果所有的都定時查,那客戶端一多,伺服器一下不就撐不住?

所以,沒有什麼疑問,伺服器主動推送是最好的方案,我不懂為什麼你覺得伺服器遍歷主動推送會比你這個定時查更不好,你先說說看為什麼你覺得你那樣做更好,大家才知道你的誤區在哪裡。。。。。。


為什麼一邊倒要廣播,感覺代碼觀受到了衝擊。拉取請求天生在時間上均勻分布,負載更平均;有一個隊列在也更方便做合批和丟棄,高負載下也是更優才對。


大部分情況下,遍歷發消息足夠了,開一個專門的廣播進程,廣播很頻繁或者多種的情況下,可依據廣播的場景分成多個進程處理,消息的廣播交由進程順序執行即可


我贊同你們主程的方案。

我們在開發消息群發功能的時候,測試過直接遍歷所有在線玩家並發送消息的方式,在單台伺服器承載幾千玩家的情況下,性能還是可以接受的。但是我們後來還是對該方案進行了一次優化,現在的群發功能大致上是這樣的:

我們的伺服器架構是客戶端連接網關伺服器,網關伺服器連接場景伺服器和社交伺服器。每組伺服器會有多個網關供客戶端連接。如果需要全服廣播,就把要廣播的消息發送給各台網關伺服器,網關伺服器收到消息後將消息存入一個隊列,然後網關伺服器後台有一個線程,不斷的檢查全服廣播隊列,如果隊列中有需要廣播的消息,則遍歷所有在線玩家,將消息發送出去。

這套方案的優勢有:

  1. 場景伺服器只要遍歷少量網關伺服器並向每台網關發送一條消息,不會卡住場景伺服器的遊戲邏輯運算。
  2. 因為有多台網關伺服器,每台網關伺服器要群發的消息數量被分攤了,所以壓力就變小了(雖然原本的壓力也不算大)。
  3. 網關伺服器的群發功能由後台線程完成,不會打斷網關伺服器本身的功能。

這套方案的劣勢是實現起來比直接遍歷在線玩家稍微複雜了那麼一絲絲(多了一兩個小時的開發調試時間)。

相比最初的方案,這套方案只是把遍歷在線玩家的工作轉移並分攤到了多台網關伺服器上,整體的思路並沒有變化。


推薦閱讀:

橙光遊戲的製作和適應人群都是學生么?該怎麼看待這一點
【Unity】工具類系列教程——配置化和規範流程
「反響這麼好,現在都很震驚」:《絕地求生》製作人談吃雞的成就與未來
【練習】我試著給俄羅斯方塊多加了一條規則進去
又要修裝備了!為什麼遊戲中會有耐久度?

TAG:遊戲開發 | 遊戲伺服器 | CC | 手機遊戲開發 |