4 关于游戏服务端架构的整理 一个大型的网落游戏服务器应该包含几个模块:网络通讯,业务逻辑,数据存储,守护监控(不是必须)。其中业务逻辑可能根据具体需要,又划分为好几个子模块。
这里说的模块可以指一个进程,或者一个线程方式存在,本质上就是一些类的封装。
对于服务器的并发性,要么采用单进程多线程,要么采用多进程单线程的方式,说说两种方式的优缺点:
一、单进程多线程的服务器设计模式,只有一个进程,但一个进程包好多个线程: 网络通讯层,业务逻辑,数据存储,分别在独立的线程中,无守护进程。
优点:
数据共享和交换方便,使用全局变量或者单例就可以,数据存储方便。 单进程,服务器框架结构相对简单,编码容易。 缺点:
所有功能只能在单个物理服务器上,不能做成分布式。 不方便监控各个线程状态,容易死锁 一个线程出错,例如内存非法访问,栈空间被破坏,那么服务器进程就退出,所有玩家掉线,影响大。 二、多进程单线程的服务器设计模式,多个进程,每个进程只有一个线程: 网路通讯,业务逻辑,数据存储,守护进程,分别在不同的进程。
优点:
各个进程可以分布在不同的物理服务器上,可以做成分布式的服务器框架,例如可以将数据存储单独放到一个物理服务器上,供几个区的服务器使用。将网络通讯进程独立出来,甚至可以做成导向服务器,实现跨服战。 可以通过守护进程监控其它进程状态,例如有进程死掉,马上重启该进程,或者某个进程cpu使用率接近100%(基本可以判断是某个逻辑死循环了), 强制kill掉该进程,然后重启。 单个服务器进程异常退出,只要不是网络通讯进程(一般这个都会比较稳定,没什么逻辑),那么就可以及时被守护进程重启,不会造成玩家掉线,只会造成在1-2秒内,某个逻辑功能无法使用,甚至玩家都感觉不到。 服务器通过共享内存进行数据交换,那么如果其中一个服务器死掉,数据还在,可以保护用户数据(当然多线程也可以使用共享内存)。 并发性相对多线程要高点。 缺点:
不方便使用互斥锁,因为进程切换的时间片远远于线程切换,对于一个高并发服务器是无法允许这么高时间片的切换代价的。因此必须设计好服务器的框架,尽量避开使用锁机制,但要保证数据不出错。 多进程编程,在各个进程间会有很多通讯,跨服务器进程的异步消息较多,会让服务器的编码难度加大。 下面先按照一个游戏的功能,将服务器的功能分块框架画出来:
点击图片可放大
以上是一个游戏服务器最基础的功能框架图,接下来要做的就是设计服务器的框架了
1. 早期的MMORPG服务器结构 Client<->GameServer<->DB 所有业务数据集中处理
优点:
简单,快速开发
缺点:
所有业务放在一起,系统负担大大增加.一个bug可能导致整个服务器崩溃,造成所有玩家掉线甚至丢失等严重后果。 开服一刹那,所有玩家全部堆积在同一个新手村.-»»卡,客户端卡(同屏人数过多渲染/广播风暴) 服务器卡(处理大量同场景消息/广播风暴) 2. 中期-用户分离集群式 GameServe1 Client | DB GameServer2 玩家不断增多->分线->程序自动或玩家手动选择进入 **缺点:**运营到后期,随着每条线玩家的减少, 互动大大减少。
3. 中后期 数据分离集群式 按地图划分服务器,当前主流 新手村问题:《天龙八部》提出了较好的解决方案,建立多个平行的新手村地图,一主多副,开服时尽可能多的同时容纳新用户的涌入,高等级玩家从其它地图回新手村只能到达主新手村。
4. 当前主流的网络游戏架构 注:在GateServer和CenterServer之间是有一条TCP连接的。而GameServer和LogServer之间的连接可以是UDP连接。这是有一个大概的图,很多地方需要细化。 **GateServer:**网关服务器,AgentServer、ProxyServer
优点:
作为网络通信的中转站,负责维护将内网和外网隔离开,使外部无法直接访问内部服务器,保障内网服务器的安全,一定程度上较少外挂的攻击。 网关服务器负责解析数据包、加解密、超时处理和一定逻辑处理,这样可以提前过滤掉错误包和非法数据包。 客户端程序只需建立与网关服务器的连接即可进入游戏,无需与其它游戏服务器同时建立多条连接,节省了客户端和服务器程序的网络资源开销。 在玩家跳服务器时,不需要断开与网关服务器的连接,玩家数据在不同游戏服务器间的切换是内网切换,切换工作瞬问完成,玩家几乎察觉不到,这保证了游戏的流畅性和良好的用户体验。 缺点:
网关服务器成为高负载情况下的通讯瓶颈问题 由于网关的单节点故障导致整组服务器无法对外提供服务的问题 解决:
**多网关技术。**顾名思义,“多网关” 就是同时存在多个网关服务器,比如一组服务器可以配置三台GameGme。当负载较大时,可以通过增加网关服务器来增加网关的总体通讯流量,当一台网关服务器宕机时,它只会影响连接到本服务器的客户端,其它客户端不会受到任何影响。 **DCServer:**数据中心服务器。主要的功能是缓存玩家角色数据,保证角色数据能快速的读取和保存 CenterServer:全局服务器/中心服务器,也叫WorldServer. 主要负责维持GameServer之间数据的转发和数据广播。另外一些游戏系统也可能会放到Center上处理,比如好友系统,公会系统。 改进:
将网关服务器细化为LogingateServer和多个GameGateServer.
5. 按业务分离式集群 由于网络游戏存在很多的业务,如聊天,战斗,行走,NPC等,可以将某些业务分到单独的服务器上。这样每个服务器的程序则会精简很多。而且一些大流量业务的分离,可以有效的提高游戏服务器人数上限。
优点:
业务的分离使得每种服务器的程序变的简单,这样可以降低出错的几率。即使出错,也不至于影响到每一个整个游戏的进行,而且通过快速启动另一台备用服务器替换出错的服务器。 业务的分离使得流量得到了分散,进而相应速度回得到提升 。 大部分业务都分离了成了单独的服务器,所以可以动态的添加,从而提高人数上限。 改进: 甚至可以将登陆服务器细化拆分建角色,选择角色服务器
6. 一种简单实用的网络游戏服务器架构 下图中每个方框表示一个独立的进程APP组件,每个服务进程如果发生宕机会影响部分用户,整体服务但不会全部中断。在宕机进程重启后,又可以并入整体,全部服务得以继续。
**gls:**game login server,游戏登录服务器,某种程序上,其不是核心组件,gls调用外部的接口,进行基本的用户名密码认证。此外需要实现很多附属的功能:登录排队 (对开服非常有帮助),GM超级登录通道(GM可以不排队进入游戏),封测期间激活用户控制,限制用户登录,控制客户端版本等。 **db:**实质上是后台sql的大内存缓冲,隔离了数据库操作,比较内存中的数据,只把改变的数据定时批量写入sql。系统的算法,开发稳定性都要求非常高。 **center:**所有组件都要在这里注册,在线玩家的session状态都在这里集中存放,和各组件有心跳连接。所有对外的接口也全部通过这里。 角色入口:玩家登录游戏后的选择角色 **gs:**game server,最核心组件,同一地图,所有游戏逻辑相关的功能,都在这里完成。 **gate:**建立和用户的常链接,主要作sockt转发,屏蔽恶意包,对gs进行保护。协议加密解密功能,一个gate共享多个gs,降低跳转地图连接不上的风险。 **IM,关系,寄售:**表示其它组件,负责对应的跨地图发生全局的游戏逻辑。 7.另一个架构图 ...