Skynet网游架构

现在的网络游戏服务器端架构中大多是以功能和场景来划分服务器结构的,划分的基本原则如下:

  1. 分离游戏中占用系统资源(CPU、内存、IO等)较多的功能并独立成服务器
  2. 以多线程或多进程的编程方式适应多核处理器
  3. 在同一个服务器架构下,应尽可能的复用某些服务器(进程级别的复用,如场景服务器)。
  4. 运行时玩家数据的保存、修改以及数据流向应该是设计的焦点,它同时也决定了服务器应该如何划分。
  5. 服务器的划分应该适度,在保证清晰的数据流向的前提下,根据游戏类型和规模尽量减少服务器或服务器进程的数量,以减少服务器之间过多的复制数据、锁冲突(使用内存共享进行通讯时)。
  6. 主要按照场景划分进程,若需要按功能划分则必须保持整个逻辑足够简单,并满足第1点和第3点。

网路游戏服务器程序一项重要的工作就时根据客户端client发过来的数据包,在服务器端模拟玩家行为操作并这些行为广播出去。因此,服务器程序在运行时就需要一些实体来保存玩家的数据,这些实体可以是一个类,也可以是一个线程,设计思想的不同采用的实体差别也会很大,这里涉及服务器端设计的一个核心问题:运行时玩家数据的保存、修改以及数据流向。

服务器架构

整个游戏系统(更偏重PvP的MMORPG)大体组成如下

  • 客户端
    运行在玩家的终端上,使用一条TCP连接和系统通讯,它接入游戏服务器网关。
  • 网关
    负责汇总所有客户端
  • 代理
    运行在网关后端,在逻辑上每个客户端都有一个代理负责翻译和转发客户端发过来的请求并作出回应。众多代理可以实现在同一个进程中,也可以在多个不同的进程。可以使用脚本虚拟机的形式跑,也可以是别的形式。推荐使用独立的LuaState来实现单个代理。
  • 数据存储
    保存玩家数据、场景数据等,前端使用代码和协议同系统其它部分沟通,后端采用Redis做存储。
  • 场景管理器
    用于管理静态场景和动态场景,若干场景服务器用于玩家在里面做漫游。

网关之后的服务是相互信任的,并组成一个虚拟网络可以相互通讯。通讯层采用zeromq,通信协议采用Google Protobuf。客户端到代理的通讯协议与网关后各个逻辑节点之间的通信协议将隔离分开设计,甚至不保证采用一致的技术实现方案以及协议设计风格。

系统设计的关键点在于代理部分,单个代理的逻辑流程如下:

  1. 等待用户认证
  2. 把认证系统交给认证服务器认证,失败则返回1并重试。
  3. 从数据库获取用户数据并转发给客户端
  4. 获取用户所在场景编号,从场景管理器中获得场景服务的位置,并申请加入场景。
  5. 从场景服务器同步环境
  6. 转发用户在场景中漫游的请求并同步场景的实时数据
  7. 一旦客户端发生异常或收到退出消息则通知场景服务器离开

这里游戏服务器设计有点小的不同是认为用户的角色在场景中的位置、动作状态甚至日后的战斗数值状态等,都应该属于场景数据的一部分而不是用户数据的一部分。用户数据中和场景相关的只包括当前所属的场景,由场景自己来保存角色在场景中的状态数据。类似于网易西游系列中玩家的坐标是玩家的属性之一,是会在持久化时存放在玩家数据中的。但从直觉上来说,虚拟角色的属性不应该包含角色的地理位置信息,那是角色的外在约束。场景更应该拥有在它其中的PC和NPC的位置以及各种状态。PC下线只因该认为是PC处于一种特殊状态(不被周围的PC/NPC所见或影响),而并没有脱离这个场景。所以更愿意把PC下线定义成为detach,而上线则是attach的操作。在这一点上,场景作为一个实体拥有自己的数据逻辑。

数据库采用Redis,可把它看成是一个远端的数据机构保存设备,Redis提供基础的Key-Value的存储功能,没有层级表。如果需要两级结构可以在Value中保存一组Hashes。为了日后拆分需求后可能会将数据拆分到不同的数据库上,可以按key的前缀把数据划分到不同的位置。

认证服务器提供三项服务:用户注册、用户名密码认证(用于SSL连接上的Web服务)、用户名密码挑战式认证(用于客户端的认证服务)。

你可能感兴趣的:(Skynet网游架构)