2016年末的時候對即時通信以及遊戲開發產生了一些興趣,並且本身這方面的知識掌握也很是少,在將來不少產品應該都會使用到長鏈接技術(物聯網IOT),所以頗有必要掌握這方面的技術。因而就在網絡上查詢相關的資料,但發現目前網絡上的開源遊戲服務器框架相對較少,而目前市面上已有的一些開源遊戲框架又不太對本身的胃口。正好17年初剛回公司的時候事情比較少,就抽時間按照本身對遊戲服務器的架構思路作了一套,取名就叫mqant了,如今已經發布到Github上,歡迎你們Fork mqant開源框架javascript
##爲何決定要從新造一個輪子?java
目前網上優秀的開源遊戲服務器框架也很多(固然與web框架比起來就少太多了),但總結起來都各有各的優缺點,下面列出我在選型過程當中的一些考量,但願你們能開放的討論,有不恰當的地方也請指正。python
###首先是開發語言 目前用於遊戲服務器開發的主要應該有如下這些語言:c++
c/c++git
優勢:github
性能很好golang
缺點:web
不過我我的不會C++後端
開源框架:服務器
skynet 底層是C 開發語言是lua, 沒有客戶端庫 kbengine 底層是C++ 開發語言可使用C#,Python 有多個平臺的客戶端庫
C#
優勢:
性能很好
缺點:
不過我我的不會C#
開源框架:
Scut 底層C# 開發語言是 C#、Python和Lua多種腳本進行開發 有多個平臺的客戶端庫 Photon 底層C# 好像是收費的,但畢竟出名 有多個平臺的客戶端庫
python
是我最想使用的一種開發語言
缺點:
開源框架:
twisted 能夠用來作網關服務器 firefly 應該很早就不維護了
java
javascript
優勢:
1. 語法靈活(這是一把雙刃刀,用起來要當心,尤爲是團隊開發中) 2. 開源庫豐富
缺點:
1. 語法上有一些缺陷 2. 跟Python同樣不支持多核 3. 對協程支持不夠好,地獄回調很可怕,雖然有一些解決方案,但用起來稍微有點彆扭
開源框架:
Pomelo 網易出的,安靜了一段時間,最近又開始維護了 有多個平臺的客戶端庫
golang
優勢:
1. 性能好,跟C/C++/C#同樣編譯型語言 2. 語法比較簡單,開發效率也比較高,接近Python 3. 語言級別支持協程 4. 單進程支持多核併發計算
缺點:
1. 開源庫較少,會golang的開發者比較少
開源框架:
leaf 接觸的第一個golang框架,設計不錯,但不支持多進程 沒有客戶端庫,須要本身實現 cellnet 剛接觸,無法評價,但好像它用了callback回調函數的設計,這樣的設計在golang應該能夠避免
###遊戲框架的不足 結合我的的實際狀況,當時我主要的選擇從 skynet Pomelo leaf 這三個框架裏面來選擇
skynet設計思路很是牛逼,看了風雲大牛的設計感受應該是一個高性能,高穩定性的遊戲服務器框架,並且有不少產品已經使用上了。 但我的認爲skynet可能也會有如下的兩個問題
Pomelo由網易團隊開發的,對多進程架構作的很是好,不過因爲javascript性能的關係Pomelo的定位也在一些中小型非即時戰鬥類遊戲,通過一段時間的學習和測試,最後仍是無奈放棄了
最後通過多方考慮,我選擇golang做爲開發語言,當時第一個接觸的就是leaf,學習開發了一段時間發現了leaf的一些不足
上面列出來的都是這幾個框架的缺點,其實這幾個框架都很是優秀,只是不一樣的需求有不一樣的要求罷了,但願你們能根據本身實際需求選擇最適合本身的框架
###對遊戲服務器框架的想法 本身內心也對遊戲服務器框架有一些本身的想法,最終決定造這個輪子。
高性能,支持多核
這在將來開發,擴展,維護會輕鬆不少,好比Python這樣一臺服務器跑上百個進程的遊戲服務器,維護起來就很讓人頭疼
支持協程
協程在客戶端中應用不大,但在服務器開發中能夠發揮極大的威力:
支持分佈式,但也支持單進程部署
有些框架寫一個demo都須要啓動多個進程,實際上在項目前期可能一臺服務器就可以支持了,我但願實現一個既能夠單進程部署又能夠分佈式部署的框架
這個需求的實現主要靠約定,只要開發的時候按分佈式環境來開發,代碼通常都不須要移植
有豐富的客戶端開發庫
讓開發者專心業務開發,不一樣再去造輪子了
###mqant框架的架構
mqant就是按照以上的思路設計的,同時設計思路上參考了Pomelo,而且也使用了leaf框架的部分代碼。
golang自己支持高性能,支持多核
支持協程 所以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){ //調用都執行完了才執行下面的代碼 }) } }) ...
支持分佈式,但也支持單進程部署
mqant是按模塊爲單位來劃分功能模塊的,能夠將一組模塊放到一個進程來運行,也能夠將全部模塊放到同一個進程來運行(即單進程模式)
mqant模塊間約定按標準的RPC來相互調用
RPC底層分兩種模式
1. 基於golang chan的單進程通訊 2. 基於rabbitmq的跨進程通訊
RPC會根據模塊間的部署狀況選用適當的通訊方式,以達到在單進程模式下RPC通訊的最低性能損耗和最快的響應時間
有豐富的客戶端開發庫
mqant沒有考慮幫開發者造一個客戶端開發庫,而是選用了目前物聯網中很是流行mqtt協議來做爲通訊協議,mqtt自己就有各個平臺的客戶端開發庫,所以能夠直接用mqtt的客戶端開發庫對接到mqant上來。實現了mqant跨平臺通訊的要求
###總結 mqant仍是一個很是新的框架,有不少地方都不完善,但我相信有更多大牛的加入進來參與完善和優化的話,mqant框架將變得更好。