【开源】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框架将变得更好。

相关文章
相关标签/搜索