類似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 |