1. 程式人生 > >關於優化遊戲服務器響應客戶端消息的一點思考

關於優化遊戲服務器響應客戶端消息的一點思考

情況 滿足 可能 轉發 邏輯 存儲 oop ado 簡單

現在假設有如下構建的遊戲服務器,遊戲服務器有一組gate服務器,用來驗證客戶端,並且通過gate服務器來與一組主服務器,然後主服務器與關系服務器進行通信。

技術分享圖片

其中relation服務器用來處理各種關系,例如好友關系,師徒關系等。現在有一個玩家A添加玩家B為好友,那麽客戶端發送給服務端的消息流程如上所示。首先gate收到客戶端消息,進行驗證等,然後轉發給Main1服務器, 這裏假設玩家A的信息存儲在Main1服務器上,然後Main1服務器檢測玩家A的各種要求,如果滿足要求,則將消息轉發給Main2服務器,這裏假設玩家B在Main2服務器,然後Main2服務器進行各種檢測,如果滿足條件,則將消息轉發給Relation服務器,Relation服務器再進行各種檢測,然後回復消息給客戶端。假設Main1的服務器檢測和Main2的服務器檢測都可以獨立完成,那麽消息邏輯可以改為:

技術分享圖片

上面的設計方案,假設玩家A和玩家B都在Gate1上。我們查看上面的兩幅圖,可以看出後面這幅圖比第一幅圖多出了一條消息,但是,響應客戶端的消息,下面這幅圖平均來說卻只需要經過三條網絡通信,上面的那種需要4條網絡消息。也就是說,正常情況下,下面的方案響應客戶端的速度更快。對客戶端來說,這無疑是一個好的消息。

那麽我們先考慮一下,采用下面這種方式需要解決的問題,首先Relation服務器需要同時等待Main1和Main2的消息,然後才可以處理,這個需要添加一定的緩存,還需要一定的區分同一條消息的機制,這個在有些情況下,可以通過協議ID來區分,另外,也可以通過一個例如64位ID來區分,如果Relation服務器對接收到的超過20s甚至更長時間的消息都不再處理,那麽64位ID可以保證在這段時間內不會重復。這種機制不需要重復,只需要在relation服務器中接收到消息時,設置當前時間,然後每隔一段時間,例如1s中清理一下就可以了。這種問題的處理,也可以參考hadoop的reduce函數的處理,當然可以參考的資料很多。然後,這種方案需要玩家在同一個Gate上,對於很多遊戲來說,一組服務器,一個Gate足以,那麽這個問題,自然不用處理。對於有多個Gate的情況,也可以如果在同一個Gate上,就采用上述做法,如果不在同一個Gate上,就采用原來的做法,只需要在協議中進行區分就可以了。至於為此添加的協議中的額外字段,不會很長,對網絡的增加的壓力應該不大。從上來看,這種方式是一種可行的方案。

我們考慮一下這種方案存在的不利之處。首先網路中增加了一條協議,增加了一條Gate到Main的消息,增加了一條Main到Relation的消息,減少了一條Main到Main的消息。這個建議測試一下,查看一下這種通信協議的增加,會不會成為遊戲服務器的瓶頸。如果Main服務器之間的通信原本比較多的話,那麽這種改變,可以減少Main之間的通信量。然後,增加了設計的復雜度,尤其是Relation的復雜度,同時增加了Relation的內存占用。對於很多遊戲來說,Main服務器的處理邏輯是瓶頸,這種設計方式,可以將部分需要Main服務器處理的邏輯,轉交給Relation服務器進行處理。如果存在很多別的服務器,使用類似的處理的話,可能會減少Main服務器的壓力,從而增加一組服務器的承載能力。所以說這種設計方式,在有些情況下,不僅可以增加服務端對客戶端的響應速度,而且可以增加一組服務器的承載量。

上面只是提供了一種簡單的設想,可以供設計遊戲服務器的程序員予以參考,如果有什麽好的建議或者意見,也歡迎反饋。

關於優化遊戲服務器響應客戶端消息的一點思考