沒開發過遊戲的人會以爲遊戲服務器是很神祕的東西。但事實上它並不比web服務器複雜,無非是給客戶端提供網絡請求服務,本質上它只是基於長鏈接的socket服務器。固然在邏輯複雜性、消息量、實時性方面有更高的要求。html
若是說web服務器的本質是http服務器,那麼遊戲服務器的本質就是socket服務器。 它利用socket通信來實現服務器與客戶端之間的交互。事實上有很多遊戲是直接基於原生socket來開發的。 相對於簡單的socket服務器,它承受着更加煩重的任務:前端
不少web應用不會基於原生的http服務器搭建,通常都會基於某類應用服務器(如tomcat)搭建,並且還會利用一些開發框架來簡化web開發。 一樣,通常遊戲服務器的開發都會在socket服務器上封裝出一套框架或相似的應用服務器。爲何使用原生的socket接口開發不夠好呢?html5
一個好的框架能夠大大簡化遊戲服務器的工做。除了遊戲自身的邏輯外,大部分的工做均可以用框架來解決。服務端的抽象,可伸縮性,可擴展性這些問題均可以經過框架來解決。 遊戲服務器框架也承擔了應用服務器的功能。能夠把框架當作容器,只要把符合容器標準的代碼扔進去,容器就運行起來了。它天然具有了抽象能力、可伸縮性和監控、管理等能力。java
在開源社區裏充斥了數不清的web服務器框架,遊戲客戶端的框架和庫也有一大堆,但惟獨遊戲服務器框架少之又少,零星有一些類庫,但完整的解決方案几乎沒有。咱們只好從商用的解決方案中拿出一些框架進行類比:node
RedDwarf是惟一一個能找到的完整的開源遊戲服務器框架,由sun出品。惋惜在它合併到Oracle之後已經中止開發了。 在設計上,RedDwarf是個分佈式架構,它在分佈式數據存儲和任務管理上投入了太多精力,並且作的過於理想化,如動態任務遷移功能的實現很是複雜,但實際應用中根本用不到。而在可伸縮性和性能的設計上不太理想。所以RedDwarf夭折了。android
SmartfoxServer是由意大利的一家遊戲公司gotoAndPlay()推出的商用遊戲服務器。 它是基於java開發的,與web應用服務器如Tomcat看上去很相似。Smartfox支持各類客戶端,且有一些成功案例。它在服務端封裝和監控管理方面實現得很完善。 但在可伸縮性上並非太理想,儘管Smartfox也支持Cluster模式,但它的擴展方式是基於jvm內存複製的。也沒有實現傳統MMORPG基於場景分區的解決方案。 Smartfox有免費版本,但徹底不開源。並且它的免費版本(達不到高併發用戶要求)很大程度是爲了吸引開發者最終購買它的收費版本。不限在線人數的收費版本價格達到3500美刀。ios
Bigworld是澳大利亞Bigworld公司開發的全套3d MMORPG遊戲解決方案,解決方案包含了客戶端和服務端。Bigworld功能很是強大,在動態負載均衡和容錯性作了不少工做。可擴展性很是強大。 它的缺點是過於重量級,對硬件要求高,且價格很是昂貴。Bigworld是專門爲3d MMORPG遊戲定製,但並不適用於中小型遊戲的開發。web
Pomelo是網易於2012年11月推出的開源遊戲服務器。它是基於node.js開發的高性能、可伸縮、輕量級遊戲服務器框架。 它的主要優點有如下幾點:算法
Pomelo目前的主要缺點是推出時間尚短,一些功能還在完善中,支持的客戶端類型還有限,目前已支持HTML五、ios、android、untiy3d等4類客戶端,將來還會支持更多的客戶端類型。json
無論是web應用仍是遊戲服務器,可伸縮性始終是最重要的指標,也是最棘手的問題,它涉及到系統運行架構的搭建,各類優化策略。 只有把可伸縮性設計好了,遊戲的規模、同時在線人數、響應時間等參數才能獲得保證。
相比web應用幾乎無限擴展的架構(前提是架構設計得好),遊戲服務器的可伸縮性相比就着差遠了。那麼是哪些因素致使遊戲沒法達到web應用的擴展能力呢? 說明:本文提到的web應用不包括相似於聊天這樣的高實時web應用,高實時web可認爲是一種邏輯較簡單的遊戲。
web應用都是基於request/response的短鏈接模式。佔用的資源要比一直hold長鏈接的遊戲服務器要少不少。Web應用能使用短鏈接模式的緣由以下:
而遊戲應用只能使用長鏈接,緣由以下:
在高併發長鏈接服務的解決方案中,目前除了傳統的C語言(過於重量級)實現,用的最多的是erlang與node.js。二者的性能指標差很少,而node.js在易用性方面毫無疑問勝出太多。
最近微博上看到時go的能撐起100萬的併發鏈接,node.js也能達到一樣的數據, Node.js w/1M concurrent connections!有node.js的長鏈接數據,它佔用了16G內存,但CPU還遠沒跑滿。
普通的web應用在交互上沒有相鄰性的概念,全部用戶之間的交互都是平等,交互頻率也不受地域限制。 而遊戲則否則,遊戲交互跟玩家所在地圖(場景)上的位置關係很是大,如兩個玩家在相鄰的地方能夠互相PK或組隊打怪。這種相鄰的交互頻率很是高,對實時性的要求也很是高,這就必需要求相鄰玩家在分佈在同一個進程裏。 因而就有了按場景分區的策略,如圖所示:
一個進程裏能夠有一個場景,也能夠有多個場景。這種實現帶來了如下問題:
遊戲中廣播的代價是很是大的。玩家的輸入與輸出是不對等的,玩家本身簡單地動一下,就須要將這個消息實時推送給全部看到這個玩家的其餘玩家。 假如場景裏面人較少,廣播發送的消息數還很少,但若是人數達到很密集的程度,則廣播的頻度將呈平方級增加。如圖所示:
假如場景中1000個玩家,每人發1條消息,若是須要其它玩家都看到的話,消息的推送量將高達1,000,000條,這足以把任何服務器撐爆。
解決這個問題的方案:
這樣廣播邏輯與具體的進程邏輯就不會相互影響了,並且因爲只有後端的場景服務器是有狀態的,前端負責廣播的服務器仍是無狀態的,所以前端服務器能夠無限擴展。
實時遊戲的服務端通常都須要一個定時tick來執行定時任務,爲了遊戲的實時性,通常要求這個tick時間在100ms以內。這些任務包括如下邏輯:
因爲實時100ms的限制,這個實時tick的執行時間必需要遠少於100ms,所以單進程內不少數據都會受到限制。
通過以上這些分析。咱們能夠獲得如今的運行架構,以下圖:
運行架構說明:
這個運行架構符合了剛纔提到的幾個伸縮性原則:
前面提到4個遊戲服務器框架,只有bigworld和pomelo符合這樣的架構,固然bigworld實現的還要更復雜。 如今的問題是,這個運行架構是個分佈式架構,並且並不簡單,那就帶來如下問題:
Node.js的特色與遊戲服務器極其符合。列舉以下:
Pomelo是基於node.js搭建的遊戲服務器框架,它在靈活性、擴展能力,輕量級調試方面具備無可比擬的優點。咱們先簡單回答第三章最末的幾個問題:
在本系列文章後面將會陸續討論pomelo是怎麼實現以上如此方便的特性, 以及這些設計帶來的啓發。
本文分析了遊戲服務器框架的市場現狀,一個高可伸縮遊戲服務器架構的設計原則及運行架構。Node.js與pomelo在解決高併發和分佈式架構中起到的做用。下文咱們將深刻分析pomelo在解決複雜的遊戲服務器運行架構中提供了哪些便利。