分布式游戏服务器设计

分布式游戏服务器设计

  • 服务器解释
  • 整体设计图
  • 网关服务器
    • 网络连接
    • 消息处理
    • 权限管理
    • 业务支持
    • 消息路由
  • 登录服务器
    • 网络连接
    • 用户注册
    • 用户登录
  • 中心服务器
    • 用户管理
    • 消息推送
    • 全局功能
  • 游戏服务器
    • 数据读取
    • 数据落地
    • 消息处理
  • 存储服务器
    • 工作模式
    • 数据一致性
  • 依赖系统
    • 服务发现
    • 消息队列
    • 存储系统

服务器解释

  • 网关服务器 Gateway Server,与客户端保持长连接并转发消息给中心服务器和游戏服务器
  • 登录服务器 Login Server,与网关服务器连接之前的登录业务
  • 中心服务器 Center Server,全局功能及消息推送
  • 游戏服务器 Game Server,游戏的核心场景实现
  • 存储服务器 Database Sever,数据库访问的连接代理

整体设计图

分布式游戏服务器设计_第1张图片

网关服务器

网络连接

  • 保持TCP连接
    • 实现多服特性时,客户端无需重新连接,提高切服的成功率和速度。
    • 对于无状态的Game Server,可以进行无感重启
    • 实现单点登录特性时,继承旧的会话,断开旧的连接,接入新的连接,无需下线
  • 流量限制
    • 防止用户通过单TCP连接内发出巨大流量,从而恶意消耗服务器的CPU资源
  • 横向扩展
    • 提高并发性能
    • 多个Gateway Server同时存在时,仍然实现单点登录特性,继承旧的会话,无需下线

消息处理

  • 消息内容压缩
    • 略微增加了CPU负载
    • 大量减少了服务器外网带宽消耗
    • 减少了传输延迟
  • 消息内容加密
    • 防止用户通过流量捕获软件获取数据包,识别内容涵义后,通过发包工具伪造数据包。
    • 消息内容中添加每次连接新生成的key,来防止用户通过录包软件发送固定的包序列充当机器人。
  • 消息序列(Sequence)验证
    • 判定客户端是否出现了发送消息的丢失或者异常
    • 防止用户通过录包软件重复发送单条消息
  • 消息完整性(CRC)验证
    • 判定切包正常
    • 判定数据包是否在通过网络层被更改过。
  • 消息时间戳验证
    • 检查消息包的时间戳,如果超时太久,则丢弃数据包。

权限管理

  • token验证
    • 通过客户端提供的token,验证接入权限
  • 黑名单
    • 获取玩家的用户id,查询用户权限,判定是否可以接入
  • 版本验证
    • 识别客户端多版本,提供多版本服务器路由支持
    • 识别客户端无效版本,提示升级客户端
  • 心跳
    • 心跳比TCP连接超时更为敏感,可覆盖更多类型的逻辑及网络异常,可及时释放连接。服务器负责监听会话的客户端心跳(PING),超时即主动断开,客户端会话也会监听服务器心跳(PONG),超时即主动断开
    • 通过心跳的时间戳来评估网络延迟,作为服务器故障判断的一种依据
    • 通过心跳的时间戳来评估网络延迟,在客户端显示网络信号状态
  • 强制下线
    • 当用户被判定为黑名单时,需要从Gateway Server上强制断开TCP连接,下次登录自动进入黑名单流程。

业务支持

  • 多级数据支持
    • 当Game Server仅拥有二级数据(比如游戏角色)的读写权限时,Gateway Server可以用来负责一级数据(比如账号昵称,创建角色)的读写业务。
  • 登录控制
    • 控制服务器的同时在线人数,尽量保证服务器的CPU使用率在50%以下,当同时在线人数超过阈值以后,不允许进入服务器,进入排队系统。
  • 排队系统
    • 玩家登录鉴权通过以后,如果当前在线人数过多,则保持登录连接,进入等待队列。
  • 在线统计
    • 通过有效连接数来统计总在线人数
  • 登录验证
    • Database登录,每次重连Gateway Server负责都去访问数据库中的账号数据表
    • Session登录, session过期前的第一次登录由Login Server访问数据库中的账号数据表,将session 键值对存入缓存。用户获得session key,在session过期前请求Gateway Server,服务器通过查询缓存进行鉴权
    • Token登录, session过期前第一次登录由Login Server访问数据库中的账号数据表,服务器不缓存token。用户获得token,在token过期前,请求Gateway Server,服务器通过算法获取token里面的加密信息进行鉴权

消息路由

  • 转发请求消息
    • 根据消息所带的组别,路由消息至对应的Game Server
    • 根据客户端所用版本,路由消息至对应的Game Server
  • 转发响应消息
    • 接收用户Id应该发出的消息,并向用户发出
    • 消息传输到错误的Gateway Server后,可以自动路由到正确的Gateway Server
    • 用户已经断开连接,丢弃数据包
  • 广播消息
    • 对于全局消息,接受消息后,遍历所有在线玩家进行发送
    • 对于特定的名单的消息,提供名单群体推送功能
    • 对于特定的频道的消息,提供频道群体推送功能

登录服务器

网络连接

  • Http服务器
    • 没有前置的Login Gateway Server,明文传输
  • TCP服务器
    • 前置Login Gateway Server,Login Gateway Server 是一个精简版的Gateway Server,仅仅用于数据包的编解码

用户注册

  • 创建新账号
    • 建立账号类型,账号名,账号id等信息
  • 支持多种用户类型
    • 游客账号
    • 自有平台账号
    • 手机账号,拥有短信验证绑定流程
    • 第三方登录,需要等待第三方服务器http验证,每一个渠道账号使用独立的mysql数据表

用户登录

  • 访问账号数据表
    • Session登录, Session过期前的第一次登录由Login Server访问数据库中的账号数据表,并将结果返回给客户端
    • Token登录,Token过期前的第一次登录由Login Server访问数据库中的账号数据表,并将结果返回给客户端

中心服务器

用户管理

  • 全局用户表
    • 所有Gateway Server和Game Server的登录都需要在Center Server注册,如果Center Server设计为多线程,则每次注册和反注册都要上锁。
  • 单点登录
    • 当相同玩家id从另一个Gateway节点登录的时候,通过全局用户表,寻找原来的用户的TCP连接所在的Gateway Server,重定向到原来的会话,取代旧的TCP连接

消息推送

  • 推送实现方式

    • 推送和全局用户表注册可以设计在一个线程当中,优势是可以不需要上锁,劣势是推送功能是非核心逻辑,全局用户表是核心逻辑,当推送达到性能瓶颈后,会影响核心逻辑的正常运行,降低了抗风险能力。
    • 推送和全局用户表不在同一个线程当中,优势是可以发挥多线程的逻辑优势,劣势是所有对全局表的访问需要上锁。
    • 推送独立进程,推送作为聊天服务器(Chat Server)独立存在,优势是和Center Server不会有性能影响,劣势是要达到数据实时互通,一种方式是Gateway Server同时注册到Center Server和Chat Server,另一种方式是Center Server主动同步数据给Chat Server
  • 全局广播

    • 标记类型为全局广播,发送给所有的Gateway Server,Gateway Server遍历所有连接,发送消息包。
  • 频道广播

    • 标记类型为频道广播,额外带上具体的频道号,频道数据保存在Gateway Server中,发送给所有Gateway Server,遍历所有连接,匹配频道,匹配成功发送消息包。
  • 名单广播

    • 维护特定的组织关系(例如公会),这个组织关系应当不在Game Server中体现,从Center Server中定位到具体Gateway Server,然后把名单和消息内容发给Gateway Server,Gateway Server比对名单内容,然后发送消息。
    • 私聊,指定特定玩家id进行通知,从Center Server中定位到具体Gateway Server,然后把名单和消息内容发给Gateway Server,Gateway Server比对名单内容,然后发送消息。

全局功能

  • 支付到账
  • 工会系统
  • 好友系统
  • 排行榜系统
  • 全局数据实时同步

游戏服务器

数据读取

  • 玩家数据读取
    • 当玩家进入Game Server时,注册到Center Server,同时Center Server通知原服务器把玩家数据在落地完成后清除,采用实时落地方案的话,则直接清除即可,Center Server通知当前服务器拉取玩家数据。
  • 游戏数据读取
    • 当进程启动时,从存储服务器中读取游戏场景需要的状态数据,数据与场景绑定,而不和玩家绑定

数据落地

  • 玩家数据落地
    • 非实时落地,则需要切换Game Server时,回存所有的玩家游戏数据,对数据库IOPS要求较低。
    • 定时落地,减少采用非实时落地方法在系统宕机后带来的回档损失。为了更加平稳的进行数据存储,在游戏业务允许的情况下,可以按照每秒存储一部分数据的分批存储模式。
    • 实时落地,数据发生修改后,立即异步通知存储服务器进行落地,对数据库IOPS要求较高。
  • 游戏场景的状态数据落地
    • 定时落地,每分钟或者每5分钟将数据整体落地一次。为了更加平稳的进行数据存储,在游戏业务允许的情况下,可以按照每秒存储一部分数据的分批存储模式。
    • 实时落地,当宕机发生以后带来的回档损失在1秒以内,对于玩家来说是无法感知回档的。

消息处理

  • 请求响应模式
    • 大部分消息满足一请求一返回的模式,玩家能在操作到达服务器后知道是否操作成功
  • 消息推送
    • Game Server的推送直接将消息转发给Gateway Server即可,Game Server需要记录玩家所在Gateway Server。
    • 一部分情况下,为了性能要求,放弃请求响应模式,定时推送消息,比如以服务器为中心的帧同步游戏。
    • 某些业务需要,一条请求多条返回,则第二条以后的消息都采用推送方式实现。
    • Game Server内业务广播,这里的广播范围往往和游戏逻辑挂钩,比如一个副本内的所有人,推送消息也往往和逻辑挂钩,直接遍历Game Server内的玩家列表推送至Gateway Server即可。

存储服务器

工作模式

  • 数据库直连型
    • 存储服务器,仅仅只是数据库集群,上层服务器,直接连接数据。
  • 线程池型
    • 存储服务器提供数据库连接,但是数据库操作的语句由上层服务器提供。
  • 业务代理型
    • 存储服务器接收自定义业务的命令,然后将命令转化为对应的数据库操作语句,操作完成以后返回结果
  • 数据缓存型
    • 在业务代理型的基础上,自身实现了一套缓存机制,在没有缓存的系统中,可以加速数据的存取效率。

数据一致性

  • 线程取模
    • 场景相关数据,按照场景或者子场景id取模选取读写线程,如何选取id取决于具体的子业务
    • 玩家相关数据,按照玩家id取模选取读写线程
  • 数据库上锁
    • mysql使用数据库行锁
    • mysql使用恰当的事务级别

依赖系统

服务发现

  • 注册服务被其他进程发现,被动建立连接
  • 通过服务发现寻找其他服务,主动建立连接

消息队列

  • 直连型
    • Zeromq
  • 服务型
    • Rocketmq
    • Rabbitmq

存储系统

  • 缓存型
    • Redis
    • Memcache
  • 存储型
    • Mongodb
    • Mysql
  • 混合型
    • Pika
    • Ssdb

你可能感兴趣的:(Game,Server)