服務器是用來處理高並發的請求,同時能夠滿足擴展的業務邏輯的需求,最重要的是滿足三點:並發性,穩定性,擴展性。
經歷過兩款上線游戲產品,見識到了游戲行業的雜亂無章,雖然和傳統軟件行業相比,少了那么些規范,但是對個人能力要求還真不比傳統軟件行業低。
今天開始,陸續利用業余時間將自己設計的一個服務器的框架貼出來,也會包好一些基本的代碼,也會用到一些開源庫。從最基礎的講起,首先看看一個實時網絡游戲服務器的框架:
目前市面上的游戲,總的來說分為兩類:
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.多進程編程,在各個進程間會有很多通訊,跨服務器進程的異步消息較多,會讓服務器的編碼難度加大。
下面先按照一個游戲的功能,將服務器的功能分塊框架畫出來:
以上是一個游戲服務器最基礎的功能框架圖,接下來要做的就是設計服務器的框架了。