大型網絡遊戲服務器的框架設計

原文

服務器是用來處理高併發的請求,同時能夠滿足擴展的業務邏輯的需求,最重要的是滿足三點:併發性,穩定性,擴展性。

經歷過兩款上線遊戲產品,見識到了遊戲行業的雜亂無章,雖然和傳統軟件行業相比,少了那麼些規範,但是對個人能力要求還真不比傳統軟件行業低。

今天開始,陸續利用業餘時間將自己設計的一個服務器的框架貼出來,也會包好一些基本的代碼,也會用到一些開源庫。從最基礎的講起,首先看看一個實時網絡遊戲服務器的框架:

 

目前市面上的遊戲,總的來說分爲兩類:

1.弱聯網類遊戲,像手機上的卡牌類遊戲(MT,Dota傳奇等),大部分邏輯在客戶端處理,不需要實時聯網,這類遊戲只有一個玩家,而且只有PVE模式,就是打遊戲中的機器人(AI),不存在玩家與玩家的實時交互。例如一場副本打鬥,只有在開始和結束,纔會連接服務器,請求獲取或者存儲數據,打鬥過程由客戶端計算完成,最後將戰鬥結果提交服務器就行了。

 

2.強聯網類遊戲,典型的就是MMORPG或者MMARPG的類型的遊戲,一般常見於端遊或者頁遊,也包含手遊。在一個地圖中,同時有很多玩家,任何一個玩家的狀態或者屬性發生變化,服務器就需要實時更新遊戲中角色的狀態,並且通知到周圍的玩家。例如在副本中,一個玩家釋放技能,攻擊範圍,傷害計算這些邏輯都是服務器來完成的,而客戶端只需要負責特效的顯示,這個過程中需要實時的數據交互。

顯然,第2種,MMORPG類遊戲需要服務器做更多的事情,對服務器的運算要求更高,實時性要求更高,自然實現起來更復雜。

 

一個大型的網落遊戲服務器應該包含幾個模塊:網絡通訊,業務邏輯,數據存儲,守護監控(不是必須),其中業務邏輯可能根據具體需要,又劃分爲好幾個子模塊。

這裏說的模塊可以指一個進程,或者一個線程方式存在,本質上就是一些類的封裝。

 

對於服務器的併發性,要麼採用單進程多線程,要麼採用多進程單線程的方式,說說兩種方式的優缺點:

 

一、單進程多線程的服務器設計模式,只有一個進程,但一個進程包好多個線程:

網絡通訊層,業務邏輯,數據存儲,分別在獨立的線程中,無守護進程。

優點:

1.數據共享和交換方便,使用全局變量或者單例就可以,數據存儲方便。

2.單進程,服務器框架結構相對簡單,編碼容易。

缺點:

1.所有功能只能在單個物理服務器上,不能做成分佈式。

2.不方便監控各個線程狀態,容易死鎖

3.一個線程出錯,例如內存非法訪問,棧空間被破壞,那麼服務器進程就退出,所有玩家掉線,影響大。

 

二、多進程單線程的服務器設計模式,多個進程,每個進程只有一個線程:

網路通訊,業務邏輯,數據存儲,守護進程,分別在不同的進程。

優點:

1.各個進程可以分佈在不同的物理服務器上,可以做成分佈式的服務器框架,例如可以將數據存儲單獨放到一個物理服務器上,供幾個區的服務器使用。將網絡通訊進程獨立出來,甚至可以做成導向服務器,實現跨服戰。

2.可以通過守護進程監控其它進程狀態,例如有進程死掉,馬上重啓該進程,或者某個進程cpu使用率接近100%(基本可以判斷是某個邏輯死循環了), 強制kill掉該進程,然後重啓。

3.單個服務器進程異常退出,只要不是網絡通訊進程(一般這個都會比較穩定,沒什麼邏輯),那麼就可以及時被守護進程重啓,不會造成玩家掉線,只會造成在1-2秒內,某個邏輯功能無法使用,甚至玩家都感覺不到。

4.服務器通過共享內存進行數據交換,那麼如果其中一個服務器死掉,數據還在,可以保護用戶數據(當然多線程也可以使用共享內存)。

5.併發性相對多線程要高點。

缺點:

1.不方便使用互斥鎖,因爲進程切換的時間片遠遠於線程切換,對於一個高併發服務器是無法允許這麼高時間片的切換代價的。因此必須設計好服務器的框架,儘量避開使用鎖機制,但要保證數據不出錯。

2.多進程編程,在各個進程間會有很多通訊,跨服務器進程的異步消息較多,會讓服務器的編碼難度加大。

 

下面先按照一個遊戲的功能,將服務器的功能分塊框架畫出來:

 

以上是一個遊戲服務器最基礎的功能框架圖,接下來要做的就是設計服務器的框架了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章