目录

服务端架构整理

  • 一个大型的网络游戏服务器应该包含几个模块:网络通讯,业务逻辑,数据存储,守护监控(不是必须)。其中业务逻辑可能根据具体需要,又划分为好几个子模块。

  • 这里说的模块可以指一个进程,或者一个线程方式存在,本质上就是一些类的封装。

单进程多线程设计

  • 网络通讯层,业务逻辑,数据存储,分别在独立的线程中,无守护进程。

优点

  • 数据共享和交换方便,使用全局变量或者单例就可以,数据存储方便。

  • 单进程,服务器框架结构相对简单,编码容易。

缺点:

  • 所有功能只能在单个物理服务器上,不能做成分布式。

  • 不方便监控各个线程状态,容易死锁

  • 一个线程出错,例如内存非法访问,栈空间被破坏,那么服务器进程就退出,所有玩家掉线,影响大。

多进程单线程设计

  • 网路通讯,业务逻辑,数据存储,守护进程,分别在不同的进程。

优点

  • 各个进程可以分布在不同的物理服务器上,可以做成分布式的服务器框架,例如可以将数据存储单独放到一个物理服务器上,供几个区的服务器使用。将网络通讯进程独立出来,甚至可以做成导向服务器,实现跨服战。

  • 可以通过守护进程监控其它进程状态,例如有进程死掉,马上重启该进程,或者某个进程cpu使用率接近100%(基本可以判断是某个逻辑死循环了), 强制kill掉该进程,然后重启。

  • 单个服务器进程异常退出,只要不是网络通讯进程(一般这个都会比较稳定,没什么逻辑),那么就可以及时被守护进程重启,不会造成玩家掉线,只会造成在1-2秒内,某个逻辑功能无法使用,甚至玩家都感觉不到。

  • 服务器通过共享内存进行数据交换,那么如果其中一个服务器死掉,数据还在,可以保护用户数据(当然多线程也可以使用共享内存)。

  • 并发性相对多线程要高点。

缺点

  • 不方便使用互斥锁,因为进程切换的时间片远远于线程切换,对于一个高并发服务器是无法允许这么高时间片的切换代价的。因此必须设计好服务器的框架,尽量避开使用锁机制,但要保证数据不出错。

  • 多进程编程,在各个进程间会有很多通讯,跨服务器进程的异步消息较多,会让服务器的编码难度加大。

服务器的功能分块

网络通讯

通讯模型

  • select epoll iocp等通信模型需要结合socket通信,对客户端的链接、断开、数据接收处理。

数据转发

  • 将逻辑层的数据下发到客户端,将客户端的数据分发到逻辑层。

  • 用到数据封包、压缩、加密、进程间的通讯等技术,如果需要也可以加入负载均衡

心跳检测

  • 定时接收客户端的心跳包,检测客户端是否非正常断开。

  • 定时发送心跳包到客户端,用于客户端检测服务器是否非正常关闭。

业务逻辑

角色管理

  • 所有进入游戏的玩家

地图场景

  • 一般使用九宫格划分地图,寻路逻辑,地图上元件的同步

副本逻辑

  • 副本中的统计,例如伤亡,斩杀数据,排行版,星级评价等,怪物事件的控制。

AI

  • 游戏里面的怪物,NPC,宠物的逻辑

战斗技能

  • 战斗主要是pvp,pve等,技能的实现,指向技能,范围技能,技能效果。

常规功能和各种玩法

  • 游戏中的常规功能,例如帮会,好友,聊天,抽奖宝箱,任务等等。

数据存取

角色存储说明

  • 角色身上的基本属性存和取,提供存取接口,角色的其他属性值是通过基本属性以及配置计算出来的。此处可以存文件也可以存数据库。

  • 功能模块数据存储:模块的数据存取,提供存取接口。例如帮会数据,好友数据等。此处可以使用文件,也可以使用数据库,由于数据结构不固定,建议使用nosql比较方便。

守护进程

监控服务器进程的状态

  • 监控服务器的cpu,内存使用状态,各个进程的运行状态,如果发现某一个服务器进程死掉及时重启。

  • 还有一些全局资源的分配,也可以由这个进程实现,例如服务器启动时候的共享内存就可以在此创建。

当前主流的网络游戏架构

  • 在GateServer和CenterServer之间是有一条TCP连接的。

  • 而GameServer和LogServer之间的连接可以是UDP连接。

优点

  • 作为网络通信的中转站,负责维护将内网和外网隔离开,使外部无法直接访问内部服务器,保障内网服务器的安全,一定程度上减少外挂的攻击。

  • 网关服务器负责解析数据包、加解密、超时处理和一定逻辑处理,这样可以提前过滤掉错误包和非法数据包。

  • 客户端程序只需建立与网关服务器的连接即可进入游戏,无需与其它游戏服务器同时建立多条连接,节省了客户端和服务器程序的网络资源开销。

  • 在玩家跳服务器时,不需要断开与网关服务器的连接,玩家数据在不同游戏服务器间的切换是内网切换,切换工作瞬问完成,玩家几乎察觉不到,这保证了游戏的流畅性和良好的用户体验。

缺点

  • 网关服务器成为高负载情况下的通讯瓶颈问题

  • 由于网关的单节点故障导致整组服务器无法对外提供服务的问题

解决方案

  • 多网关技术。就是同时存在多个网关服务器,比如一组服务器可以配置三台GameGme。当负载较大时,可以通过增加网关服务器来增加网关的总体通讯流量,当一台网关服务器宕机时,它只会影响连接到本服务器的客户端,其它客户端不会受到任何影响。

  • DCServer 数据中心服务器。主要的功能是缓存玩家角色数据,保证角色数据能快速的读取和保存

  • CenterServer 全局服务器/中心服务器,也叫WorldServer. 主要负责维持GameServer之间数据的转发和数据广播。另外一些游戏系统也可能会放到Center上处理,比如好友系统,公会系统。

  • 将网关服务器细化为LogingateServer和多个GameGateServer

按业务分离式架构

  • 由于网络游戏存在很多的业务,如聊天,战斗,行走,NPC等,可以将某些业务分到单独的服务器上。这样每个服务器的程序则会精简很多。而且一些大流量业务的分离,可以有效的提高游戏服务器人数上限。

优点

  • 业务的分离使得每种服务器的程序变的简单,这样可以降低出错的几率。即使出错,也不至于影响到每一个整个游戏的进行,而且通过快速启动另一台备用服务器替换出错的服务器

  • 业务的分离使得流量得到了分散,进而相应速度回得到提升

  • 大部分业务都分离了成了单独的服务器,所以可以动态的添加,从而提高人数上限

  • 甚至可以将登陆服务器细化拆分建角色,选择角色服务器

一种简单实用的网络游戏服务器架构

  • gls:game login server,游戏登录服务器,某种程序上,其不是核心组件,gls调用外部的接口,进行基本的用户名密码认证。此外需要实现很多附属的功能:登录排队 (对开服非常有帮助),GM超级登录通道(GM可以不排队进入游戏),封测期间激活用户控制,限制用户登录,控制客户端版本等。

  • db:实质上是后台sql的大内存缓冲,隔离了数据库操作,比较内存中的数据,只把改变的数据定时批量写入sql。系统的算法,开发稳定性都要求非常高。

  • center:所有组件都要在这里注册,在线玩家的session状态都在这里集中存放,和各组件有心跳连接。所有对外的接口也全部通过这里。

  • 角色入口:玩家登录游戏后的选择角色

  • gs:game server,最核心组件,同一地图,所有游戏逻辑相关的功能,都在这里完成。

  • gate:建立和用户的常链接,主要作sockt转发,屏蔽恶意包,对gs进行保护。协议加密解密功能,一个gate共享多个gs,降低跳转地图连接不上的风险。

  • IM,关系,寄售:表示其它组件,负责对应的跨地图发生全局的游戏逻辑。

另一个架构图

  • 1 是一条WebService的管道,在用户激活该区帐号,或者修改帐号密码的时候,通过这条通道来插入和更新用户的帐号信息。

  • 2 也是一条WebService管道,用来获取和控制用户该该组内的角色信息,以及进行付费商城代币之类的更新操作。

  • 3 是一条本地的TCP/IP连接,这条连接主要用来进行服务器组在登陆服务器的注册,以及登陆服务器验证帐户后,向用户服务器注册帐户登陆信息,以及进行对已经登陆的帐户角色信息进行操作(比如踢掉当前登陆的角色),还有服务器组的信息更新(当前在线玩家数量等)。

  • 4 也是一条本地TCP/IP连接,这条连接用来对连接到GameServer的客户端进行验证,以及获取角色数据信息,还有传回GameServer上角色的数据信息改变。

  • 5 这条连接也是一条本地的TCP/IP连接,它用来进行公共信息服务器和数个游戏服务器间的交互,用来交换一些游戏世界级的信息(比如公会信息,跨服组队信息,跨服聊天频道等)。

  • 6 这里的两条连接,想表达的意思是,UserServer和GameServer的Agent是可以互换使用的,也就是玩家进入组内之后,就不需要再切换 Agent。如果不怕乱套,也可以把登陆服务器的Agent也算上,这样用户整个过程里就不需要再更换Agent,减少重复连接的次数,也提高了稳定性。 (毕竟连接次数少了,也降低了连不上服务器的出现几率)

  • 在这个架构里面,GameServer实际上是一个游戏逻辑的综合体,里面可以再去扩展成几个不同的逻辑服务器,通过PublicServer进行公共数据交换。

  • UserServer实际上扮演了一个ServerGroup的领头羊的角色,它负责向LoginServer注册和更新服务器组的信息(名字,当前人数),并且对Agent进 行调度,对选择了该组的玩家提供一个用户量最少的Agent。同时,它也兼了一个角色管理服务器的功能,发送给客户端当前的角色列表,角色的创建,删除, 选择等管理操作,都是在这里进行的。而且,它还是一个用户信息的验证服务器,GameServer需要通过它来进行客户端的合法性验证,以及获取玩家选择 的角色数据信息。

采用这种架构的游戏,通常有以下表现

  • 用户必须激活一个大区,才能在大区内登陆自己的帐号

  • 用户启动客户端的时候,弹出一个登陆器,选择大区

  • 用户启动真正的客户端的时候,一开始就是输入帐号密码

  • 帐号验证完成之后,进行区内的服务器选择

  • 服务器选择完成之后,进入角色管理。同时,角色在不同的服务器里不能共享