本系列准备重点介绍MMO游戏,之前本来打算把卡牌游戏简单介绍下,但是经历过MMO游戏开发之后,发现MMO游戏的架构可以适用于很多类型的游戏。本文先介绍支持单服支撑2万人以下的经典架构。学习不能好高骛远,当把经典的传统架构学好之后,再去思考支持百万在线的架构,很多疑惑将会迎刃而解。
这套架构是比较经典的,许多MMO游戏依旧在使用该架构。大部分MMO游戏,就是新服的时候会涌入较多的人,当旧服生态稳定后,基本上在线人数不超过一千人。本文重点介绍笔者上一个MMO游戏的架构和设计思路。
该架构是比较经典的传统MMO架构,他的优点和缺点也比较明显。先简单介绍下各个进程的作用,然后再分析下该架构下会有什么问题。
游戏数据落地存盘用的是mysql数据库,其实也可以替换成其他数据库。mysql这种关系数据库的话,其实对游戏存储来说并不友好。游戏数据一般会变化频繁,如果经常增删字段,那么势必会对数据库带来不必要的开销。所以一般的做法,就是对容易频繁变化的数据做序列化和反序列化,这样的话开发就会相对容易了,当然同时也会带来性能上的开销。
目前我们的redis集群主要是用来缓存数据。redis是内存数据库,所以在性能上是有很大的优势,能支持高频的访问。与mysql不同的是,我们的redis是全服共享的集群。目前游戏的登录就是通过redis来做的,实现了解耦,登录系统是游戏的核心系统之一,具体实现会在后面的博客展开。
GateServer:网关服务器,通常是多组,暴露给客户端的游戏入口。客户端选择好区服之后,会选取较空闲的Gate进行连接,目前的做法是在区服信息里面带上当前的Gate组信息,由客户端通过简单的算法选择Gate。GateServer主要的功能就是对消息加密和解密,转发消息以及广播消息。因为只有gate对外,当gate被攻击了,也不会影响其他进程,在一定程度上保证了游戏服务器的安全。而且gate一般是无状态的,挂了重启即可。
GameServer:游戏逻辑服,通常是多组,游戏的核心进程,大部分数据以及逻辑都在GameServer上。一般,一个GameServer会管理几个地图(或者场景),一个GameServer通常能承载1000人左右。因为MMO游戏的战斗是整个逻辑服性能的瓶颈,当同屏人数过多时,并且同时战斗时,消息会数量级增大。所以一般会针对不同的副本玩法,做一些优化,比如某些玩法只在特定的GameServer上,某些GameServer只管理主城地图。
LoginServer:登录服务器,单点,主要功能是用于登录验证,以及地图管理。控制不同的地图在GameServer上创建,以及分线管理。玩家登入登出以及切换地图一般通过LoginServer来控制。
CenterServer:中心服务器,单点。主要功能是游戏玩法和游戏逻辑的中控管理,比如邮件,军团系统,好友系统,活动系统,交易系统,排行榜等等。因为中心服务器是单点,所以在设计系统的时候,需要考虑性能问题,对于一些频繁的查询操作,可以在redis或者GameServer做缓存,减缓中心服务器的压力。
WorldServer: 世界服务器,单点。主要功能就是用于跨服的管理,上面主要的系统是聊天和组队,以及跨服副本的管理。因为mysql是分区分库的,所以跨服的DBS不存储角色的数据。角色数据的落地是通过跨服组的GS把SQL语句打包到原服务器LoginServer存储的。跨服的DBS一般存储玩法的数据,比如跨服排行榜数据等
ProxyServer:代理服务器,这个主要作用就是操作redis的代理,还有一些其他运营后台推送过来的数据。
整个架构就是这样子,这个架构对于单服1到2万来说,基本上没啥压力,做好单点的性能压测,一般来说是足够的。优点就是结构简单,GateServer和GameServer是可扩展的。缺点就是容灾较困难,并且单点容易出现性能问题,CenterServer集合功能太多,一旦挂了对整个游戏有很严重的影响。目前主流的技术都是微服务和分布式,其实这些技术在游戏上也可以应用的。当做好分布式或者微服务的时候,容灾也变得相对简单了。对于MOBA游戏这种开房间类型的游戏来说,更为适合,当然MMO游戏经过改造也是适用的。