【開源】golang高性能分佈式遊戲服務器框架-mqant

2016年末的時候對即時通信以及遊戲開發產生了一些興趣,並且本身這方面的知識掌握也很是少,在將來不少產品應該都會使用到長鏈接技術(物聯網IOT),所以頗有必要掌握這方面的技術。因而就在網絡上查詢相關的資料,但發現目前網絡上的開源遊戲服務器框架相對較少,而目前市面上已有的一些開源遊戲框架又不太對本身的胃口。正好17年初剛回公司的時候事情比較少,就抽時間按照本身對遊戲服務器的架構思路作了一套,取名就叫mqant了,如今已經發布到Github上,歡迎你們Fork mqant開源框架javascript

##爲何決定要從新造一個輪子?java

目前網上優秀的開源遊戲服務器框架也很多(固然與web框架比起來就少太多了),但總結起來都各有各的優缺點,下面列出我在選型過程當中的一些考量,但願你們能開放的討論,有不恰當的地方也請指正。python

###首先是開發語言 目前用於遊戲服務器開發的主要應該有如下這些語言:c++

  1. c/c++git

    優勢:github

    性能很好golang

    缺點:web

    不過我我的不會C++後端

    開源框架:服務器

    skynet
     底層是C 開發語言是lua,
     沒有客戶端庫
    
     kbengine
     底層是C++ 開發語言可使用C#,Python
     有多個平臺的客戶端庫
  2. C#

    優勢:

    性能很好

    缺點:

    不過我我的不會C#

    開源框架:

    Scut
     底層C#   開發語言是 C#、Python和Lua多種腳本進行開發
     有多個平臺的客戶端庫
    
     Photon
     底層C#   好像是收費的,但畢竟出名
     有多個平臺的客戶端庫
  3. python

    是我最想使用的一種開發語言

    1. 開發效率很是高
    2. 支持協程,能開發出高併發性的遊戲,並且代碼可讀性好
    3. 目前有不少遊戲公司應該都使用的是Python做爲後端遊戲服務器開發語言,有相對成熟的案例

    缺點:

    1. Python很致命的一個問題是進程不能利用多核,也就是說一個進程只能利用一個CPU進行計算,若是要用多核就須要新開進程,這樣會形成服務器的維護成本增長,並且開發項目時所須要考慮的問題也更多

    開源框架:

    twisted  能夠用來作網關服務器
     firefly  應該很早就不維護了
  4. java

    1. 沒有找到比較好的開源框架
    2. 對協程支持不夠好
    3. 開發效率較低
  5. javascript

    優勢:

    1. 語法靈活(這是一把雙刃刀,用起來要當心,尤爲是團隊開發中)
     2. 開源庫豐富

    缺點:

    1. 語法上有一些缺陷
     2. 跟Python同樣不支持多核
     3. 對協程支持不夠好,地獄回調很可怕,雖然有一些解決方案,但用起來稍微有點彆扭

    開源框架:

    Pomelo 網易出的,安靜了一段時間,最近又開始維護了
     有多個平臺的客戶端庫
  6. golang

    優勢:

    1. 性能好,跟C/C++/C#同樣編譯型語言
     2. 語法比較簡單,開發效率也比較高,接近Python
     3. 語言級別支持協程
     4. 單進程支持多核併發計算

    缺點:

    1. 開源庫較少,會golang的開發者比較少

    開源框架:

    leaf 		接觸的第一個golang框架,設計不錯,但不支持多進程
     沒有客戶端庫,須要本身實現
     cellnet	剛接觸,無法評價,但好像它用了callback回調函數的設計,這樣的設計在golang應該能夠避免

###遊戲框架的不足 結合我的的實際狀況,當時我主要的選擇從 skynet Pomelo leaf 這三個框架裏面來選擇

skynet設計思路很是牛逼,看了風雲大牛的設計感受應該是一個高性能,高穩定性的遊戲服務器框架,並且有不少產品已經使用上了。 但我的認爲skynet可能也會有如下的兩個問題

  1. Actor模式可能對架構能力比較高,不如rpc模式明瞭
  2. skynet使用第三方網絡庫的時候可能須要造輪子,要放開膀子開發有些難,跟python tornado的同樣,要寫出高性能的程序也對開發人員有必定的要求

Pomelo由網易團隊開發的,對多進程架構作的很是好,不過因爲javascript性能的關係Pomelo的定位也在一些中小型非即時戰鬥類遊戲,通過一段時間的學習和測試,最後仍是無奈放棄了

最後通過多方考慮,我選擇golang做爲開發語言,當時第一個接觸的就是leaf,學習開發了一段時間發現了leaf的一些不足

  1. 不支持多進程
  2. 沒有客戶端開發庫,須要本身造輪子

上面列出來的都是這幾個框架的缺點,其實這幾個框架都很是優秀,只是不一樣的需求有不一樣的要求罷了,但願你們能根據本身實際需求選擇最適合本身的框架

###對遊戲服務器框架的想法 本身內心也對遊戲服務器框架有一些本身的想法,最終決定造這個輪子。

  1. 高性能,支持多核

    這在將來開發,擴展,維護會輕鬆不少,好比Python這樣一臺服務器跑上百個進程的遊戲服務器,維護起來就很讓人頭疼

  2. 支持協程

    協程在客戶端中應用不大,但在服務器開發中能夠發揮極大的威力:

    1. 高併發,能最大的利用cpu資源
    2. 異步開發同步化,免去了回調函數設計,避免了地獄回調
  3. 支持分佈式,但也支持單進程部署

    有些框架寫一個demo都須要啓動多個進程,實際上在項目前期可能一臺服務器就可以支持了,我但願實現一個既能夠單進程部署又能夠分佈式部署的框架

    1. 單進程可以實現高性能
    2. 分佈式部署不用從新設計編碼

    這個需求的實現主要靠約定,只要開發的時候按分佈式環境來開發,代碼通常都不須要移植

  4. 有豐富的客戶端開發庫

    讓開發者專心業務開發,不一樣再去造輪子了

###mqant框架的架構

mqant就是按照以上的思路設計的,同時設計思路上參考了Pomelo,而且也使用了leaf框架的部分代碼。

  1. golang自己支持高性能,支持多核

  2. 支持協程 所以mqant的RPC通訊均可以按同步來寫, 例如:

    //遠程調用 Login模塊的getRand方法
     result,err:=m.RpcInvoke("Login","getRand",roomName)
     if err==nil{
     	//getRand 調用成功了,再作下面的遠程調用
     	result,err:=m.RpcInvoke("Login","getName",roomName)
     }
     //上面的調用都執行完了才執行下面的代碼
     ....
    
     result 是遠程調用成功之後的返回值
     err		是遠程調用失敗的信息
    
     以上代碼很是清晰,跟普通的函數調用基本同樣,但若是用回調函數的話,以下:
    
     m.RpcInvoke("Login","getRand",roomName,func(result string,err string){
     		if err!=nil{
     			m.RpcInvoke("Login","getName",roomName,func(result string,err string){
     				//調用都執行完了才執行下面的代碼
     			})
     		}
     })
     ...
  3. 支持分佈式,但也支持單進程部署

    mqant是按模塊爲單位來劃分功能模塊的,能夠將一組模塊放到一個進程來運行,也能夠將全部模塊放到同一個進程來運行(即單進程模式)

    mqant模塊間約定按標準的RPC來相互調用

    RPC底層分兩種模式

    1. 基於golang chan的單進程通訊
     2. 基於rabbitmq的跨進程通訊

    RPC會根據模塊間的部署狀況選用適當的通訊方式,以達到在單進程模式下RPC通訊的最低性能損耗和最快的響應時間

  4. 有豐富的客戶端開發庫

    mqant沒有考慮幫開發者造一個客戶端開發庫,而是選用了目前物聯網中很是流行mqtt協議來做爲通訊協議,mqtt自己就有各個平臺的客戶端開發庫,所以能夠直接用mqtt的客戶端開發庫對接到mqant上來。實現了mqant跨平臺通訊的要求

###總結 mqant仍是一個很是新的框架,有不少地方都不完善,但我相信有更多大牛的加入進來參與完善和優化的話,mqant框架將變得更好。

相關文章
相關標籤/搜索