類似coc這種全球同服,並且註冊玩家與在線玩家龐大的遊戲,伺服器端架構該如何設計呢?

因為是本著提升架構能力為出發點,所以不考慮,skynet,各種像阿里雲,騰訊雲之類的現成解決方案


剛好做過幾款類似的全球唯一服的伺服器,就簡單談談,不好莫怪。

首先,遊戲伺服器是IO密集型伺服器,它的主要瓶頸在網路IO,而不是CPU,這點要記住了。所以經常伺服器問題都會出現在網路IO,帶寬,資料庫磁碟讀寫上面,而非CPU上面。

其實全球同服也就是大量在線嘛,比如C1000k,甚至更多。同服,只是你看起來同服,而不是他本身就在同一個伺服器上,或者同一個進程上,這是完全不現實的。一個好的伺服器進程,能同時承載10k的遊戲玩家(還依賴於遊戲邏輯複雜度)已經不錯了。其實要全球同服,就是堆伺服器進程嘛。

講一下我用過的其中一種架構模型,也是公司按著bigworld架構設計的:

1.Gate:首先要有一個(多個)Gate(網關)伺服器,負責客戶端連接及消息轉發到GameServer(遊戲服)(選服邏輯),保持客戶端到服務端的連接

沒有任何邏輯,只做消息加密和解密,以及客戶端和伺服器消息的轉發(相當於兩者之間的橋樑).

2.GameServer:GameServer是主要的遊戲進程,提供遊戲邏輯功能(採用單進程(或者單線程)模型,遊戲伺服器的瓶頸從來不在CPU,所以只做邏輯功能的話單線程足夠了,在這裡沒必要用多線程或多進程)。

3.DBManager:實現資料庫的讀寫,方便Game伺服器非同步讀寫資料庫的數據(有些把資料庫讀寫放在遊戲服,沒有單獨的伺服器,那恐怕遊戲服單進程就不夠用了)。

4.GameManager:負責管理所有的GameServer,GameServer之間消息轉發,提供廣播到所有Game的功能。

客戶端連Gate,Gate連GameServer,GameServer連DBManager,GameManager管理所有的GameServer並通知所有的Gate。

除了GameManager只有一個,理論上Gate,GameServer,DBManager都可以擴展到多個實例,你要實現全球唯一服,理論上就是擴展GameServer,那麼怎麼讓他們看起來在一個服呢?其實很簡單,COC大多數都是單服玩法,只有交互玩法的時候你才能感受到它是同一個服。

主要講講GameServer,這是主要的處理伺服器邏輯的地方,一般單進程就可以了,一個epoll_wait

hold住全場,然後做分發,理論上cpu都能承載的住,而epoll能處理的上限,一般跟機器的內存有關,遠大於1024,正常的也達到100k,當然考慮到邏輯的複雜度,一個實例一般處理的連接接近10k就可以了。

那怎麼處理100k,1000k甚至更多了,那就多個實例,那這樣還是唯一服嗎?是的,至少可以看起來是,遊戲自然有單人玩法和多人玩法,單人玩法自然自己在自己的服就可以了,誰也不知道是不是跟別人一個服。

當然有全服的排行榜,好友系統之類的怎麼辦呢,其實很簡單,我們不是有GameManager嗎,它就是負責做這事的,每當你發個好友請求,GameManager廣播一條消息,然後如果有某個GameServer存在這個玩家,那就回應你,你們就可以相互通信了,更簡單的想辦法獲取玩家的伺服器ID號,直接通過GameManager轉發給那個伺服器,自然就可以通信了,就像在同一個伺服器一樣。

排行榜呢,最簡單的,指定一個伺服器,或者單獨開闢一個伺服器做排行榜,所有數據變動都通知這個伺服器,然後伺服器自然就能排行了,然後再廣播。

雙人戰鬥或者多人副本呢?

像COC這樣的,掠奪戰,我們當時的做法就是,直接搜到敵方,然後把自己的玩家,士兵軍隊等需要的數據序列化之後,傳到對面的伺服器去,反序列化,然後直接開打,打完再把數據傳回來。

更多人的呢,那就方便點,再開闢一類伺服器,叫BattleServer,專門負責多人玩法,副本玩法之類的,多人的時候,把所有的多人數據遷移到BattleServer,然後多人(副本玩法)結束的時候,再通過GameManager把數據遷移回原來的伺服器。

這樣看,其實全球唯一服也就沒有那麼高大上了。

如果有興趣,可以看看KBEngine伺服器引擎,作者按照bigworld架構設計的,可以滿足你的要求。

可以看我的博客:手游伺服器開發技術詳解


我們也做了幾款類似的遊戲,分享下。

【架構】

1、login/gate。所有client連接都首先連接到這裡,登陸認證後,給client分配一個game節點ip和port。

2、game。真正的遊戲業務服,login會通過玩家信息做個分發,把玩家分發到指定的game,client通過返回的ip和port直連到指定game,並斷開和login的鏈接。

3、world。大世界管理服,作用是管理game,以及進行game之間的消息分發。

4、cache。一些公用的數據會通過鍵值區分開放到緩存中,比如排行榜這類。可使用redis實現,可以作為全局的,也就是所有game節點都可訪問。

5、db。可以使用一些中間件做mysql集群。但推薦使用mongodb 的 sharding,很好用,尤其是3.2版本後使用wiredtigger引擎,性能好而且使用方便。

【依賴關係】

1、login作為game的master要先啟動,且game啟動後要註冊到login。也就是login持有可用的game的列表。

2、world也作為game的master。game也需要註冊到world,方便world進行分發。

3、db如果使用mongodb,可以直接使用它的cluster集群,可以做master-slave高可用以及shard集群。

4、cache如果使用redis也可以使用做HA高可用和cluster集群。

【熱點】

1、大並發鏈接的時候login可能會是熱點,不過沒關係。可以坐下lvs或者nginx的loadbalance分流即可。

2、cache。因為是全局的,可以如上說做ha和sharding。

3、db。如上所述做ha和sharding。

【利器】

1、可以使用zookeeper坐下game的集群管理。

2、可以使用dubbo坐下rpc服務治理。

先寫到這裡,大概就是這樣。


coc其實也是分區的。你可以仔細觀察公眾頻道的信息,兩台手機看到的不一樣


推薦閱讀:

推薦一個持續監測伺服器cpu、內存、網路等的軟體(MS 系統)?
在一個伺服器上面怎麼放兩個網站呀?
node.js應用高並發高性能的核心關鍵本質是什麼?
《魔獸爭霸III》是如何實現野怪同步的?
伺服器被 DDos 攻擊就沒有有效的處理方法嗎?

TAG:伺服器 | 伺服器架構 | 海島奇兵BoomBeach |