MMO 游戏服务器引擎设计

一、 网络游戏开发的基本流程

◆ 项目文档

◆ 开发的进行和文档准备流程

◆ 技术人员文档

二、 MMO游戏架构

◆ MMO游戏特点

◆ MMO架构的特有内容

三、 策划文档

◆ 考虑示例游戏的题材

◆ 详细设计文档

◆ MMO庞大的游戏设定

◆ 5种设计文档

系统的基本结构图

进程关系图

资源评估文档

协议定义文档

数据库设计图

◆ 设计上的重要判断

四、 系统基本结构图

◆ 系统基本结构图的基础

◆ 服务器必须具有可扩展性 ---- 商业模式的确认

◆ 各瓶颈 ---- 扩展方式的选择

◆ MMO客户端特有的渲染性能瓶颈

◆ 解决服务器/数据库的瓶颈

空间分割法

实例法

平行世界方式

◆ 一台服务器负责整个游戏世界(什么都不做)

 

◆ 服务器的空间分割法 ---- 解决服务器的瓶颈

 

◆ 实例法 ---- 解决服务器的瓶颈

◆ 平行世界方式 ---- 解决数据库瓶颈

1、 同时采用平行世界和空间分割法

2、 同时采用空间分割、平行世界、实例法

◆ 同时采用多种方法 ---- 大量玩家在线时的数据

◆ 各种方式的引入难度

◆ 各个世界中数据库服务器的绝对性能提高

◆ K-Online的设计估算---- 首先从同时在线开始

◆ 据游戏逻辑的处理成本估算

◆ 据游戏数据库的处理负荷估算 ---- 角色数据的保存频率和数据库负荷的关系

◆ 可扩展性的最低讨论结果及进一步的用户体验追求

◆ 服务器的基本结构

五、 进程关系图

◆ 服务器连接的结构 ---- 只用空间分割法/使用平行世界方式和空间分割法

proxy与gmsv的关系是据gmsv处理逻辑的性能瓶颈和proxy连接数量瓶颈决定的m:n关系

(1) 只是用空间分割法;

蓝色是使用现有的服务器、黑色需要独立制作、准备

(2)同时使用平行世界和空间分割法

图 5-1-2-1 同时使用平行世界和空间分割法

使用平行世界方式进行扩展的关键是将dbsv分为dbsv1、dbsv2、dbsv3这样的多个数据库服务器,从而线性的提高存储游戏数据时的写入性能。

● authsv是共通的

● 分为5个平行世界,1个平行世界允许同时连接6000名玩家,总共允许3W玩家同时访问游戏

● 1个平行世界分为8个区(8核,8个进程)

● 1个平行世界准备360个实例(16核,
16个进程)

● 玩家继续增加的情况下,追加平行世界

图 5-1-2-1中,各个服务器的分布情况:

① 尽量使得authsv进程并行化

② 各个世界中,worldsv为1个进程,gmsv中地区用到8个进程,
实例用到16个进程,不能动态增减。

③ proxy与gmsv的个数相同

④ dbsv、MySQL、备份用的MySql每个世界1套

⑤ msgsv是所有世界共用的,尽量并行化,实际的进程数据要根据之后的基准测试来决定

⑥ logsv是所有世界共用的,只要1个进程,生成多少日志要在开发中决定

进程所需的服务器资源


进程


CPU(内核)


备注


RAM


存储器


TCP会话数


Gmsv


W * (8 + 16)


K-Online中的世界数据都是二维的,故数据量没那么大,内存每个内核1G就够,CPU成为性能瓶颈可能性高


上述 * 1G


不需要


3+


Loginsv


W * 1


通信缓存部分的内存,实际上loginsv很少成为瓶颈


上述 * 500M


不需要


2+


Dbsv


W * 1


通信缓存部分的内存,dbsv中的Mysql大多会成为瓶颈


上述 * 500M


不需要


(8 + 16)+


Proxy


W * (8 + 16)


通信缓存部分是十分必要的,关键是TCP/IP的QPS性能可达到多少,但1个proxy只为1个gmsv,就不会成为瓶颈


上述 * 500M


不需要


500+


Msgsv


W * 2


对玩家的在线状况进行管理,防止二次登录,内存和CPU都可能以外的成为瓶颈,beta测试前要进行基准测试


上述 * 2G


不需要


3+


Worldsv


W * 1


因必须一定程度上把握各个gmsv的玩家状态,经常增加排序和搜索处理,故CPU和内存都容易成为瓶颈


上述 * 2G


不需要


(8+16)+


Commondbsv


1


平行世界方式下,进行与世界无关的持久化处理;存储设备更多地使用后端的Mysql,Mysql可能成为瓶颈


上述 * 500M


不需要


W


Authsv


W * 1


只具有结算公司网关的功能,通信缓存部分的内存即可,authsv与结算公司间的线路延迟时,会成为瓶颈


上述 * 500M


不需要


2+


Logsv


1


不考虑日志存储量瓶颈,若gmsv等前端服务器突然发送大量日志,网络QPS会成为瓶颈


1G


10T


(10 + W * 30)+


Mysql


W * 2

 

内核数 * 8G


W * 100G


1+

资源估算分为两大类型:CPU为中心的服务器、存储为中心的服务器

■ CPU为中心的服务器:

CPU较快,内核较多,内存一般,存储量少,容错性低,一次性的

■ 存储为中心的服务器:

CPU一般,内核一般,内存高,存储量大,容错性高,使用长期

◆ 使用平行世界方式进行扩展的关键

六、 资源估算文档

◆ 以进程列表为基础估算服务器资源

◆ 分别以CPU、存储为中心的服务器

◆ 服务器资源估算 ---- 成本估算

七、 协议文档

◆ 协议的基本性质

C/SMMO中,TCP的基础上构建专用的协议,协议的基本性质:

■ 哪些作为Server,哪些作为Client

■ 长连接还是短链接,取决于是否需强连网进行频繁的网络消息发送

■ 与服务器端间的会话是否是有状态的,是否要进行管理各个会话(例如:定期统计在线玩家人数,可做在Client与Server的连接之间)

■ 是否管理认证时的状态

■ Client与Server之间的,Server与Server之间的m
:n关系,取决于硬件系统和软件系统设计及处理的性能瓶颈的关系,例如:通常,一个Proxy远远满足于一个GameServer的处理性能需求

■ 是否需要服务器的主动推送(Push)

■ 连接中断时,是否需要立即结束服务

进程种类:

■ 客户端 cli

■ 逻辑服务器 gmsv

■ 登录服务器 loginsv

■ 消息服务器 msgsv

■ 数据库服务器 dbsv

■ 逆向代理服务器 proxy

■ 世界服务器 worldsv

■ 全体公用服务器 commondbsv

■ 收费认证服务器 authsv

■ 日志服务器 logsv

■ DBMS

■ 结算公司服务器 paysv

表7-1 进程间的关系

 
cli


gmsv


loginsv


msgsv


dbsv


worldsv


com-dbsv


authsv


logsv


DBMS


paysv


cli

 



             

gmsv

       



 

   

loginsv

       





   

msgsv

       



 

   

dbsv

               


 

worldsv

               

   

com-dbsv

               

   

authsv

               

 


logsv

                     

DBMS

                     

paysv

                     

协议性质划分原则:连到谁,就叫谁

■ gmsv协议

■ loginsv协议

■ msgsv协议

■ dbsv协议(gmsv、loginsv、msgsv都连接dbsv,就叫dbsv协议)

■ worldsv协议(gmsv、loginsv、msgsv都连接worldsv,就叫worldsv协议)

■ com-dbsv协议(gmsv、loginsv、msgsv都连接com-dbsv,就叫com-dbsv协议)

■ authsv协议

■ logsv协议(gmsv、loginsv、msgsv、dbsv、worldsv、com-dbsv、authsv)

表7-2 协议基本性质关系

 
Cli


gmsv


loginsv


msgsv


dbsv


worldsv


com-dbsv


authsv


logsv


DBMS


paysv


Cli

 

state

n:1

push


每次连接n:1


stateful

n:1

push

harmful


           

Gmsv

       
n:1


n:1


n:1

 
n:1

harmful

   

loginsv

       
n:1


n:1


n:1


n:1


n:1

harmful

   

msgsv

       
n:1


n:1


n:1

 
n:1

harmful

   

Dbsv

             


n:1

harmful


1:1

 

worldsv

               
n:1

harmful

   

com-dbsv

             


n:1

harmful


1:1

 

authsv

               
n:1

harmful

 
n:1


logsv

                     

DBMS

                     

paysv

                     

state/stateful:需要服务器端管理各个会话的状态

push:需推送信息

harmful:连接中断时,不需要立即结束服务

表7-2各服务连接中断时,是否需要立即结束服务

① cli连接gmsv,连接中断时,MMO中是需要立即停止游戏的;但msgsv是聊天服务器,若出问题,游戏还是可以继续进行的,不需立即关闭客户端

② 各服务器间的连接,若前端服务器与后端服务器的连接中断或超时的情况下,前端服务器则停止运行。特别是dbsv异常的情况下,无法保存数据,若还是运行游戏,则产生与存储数据的不一致,这情况得避免,没有等待几秒重连的空闲

③ DBMS,authsv都是低频访问的服务器,则dbsv、authsv都得停止,而引起其余服务器都得停止

协议设计的基本原则:

■ 与后端服务器通信时,尽可能无状态;是可做到对于所有后端服务器无状态的

■ MMO系统,战斗、聊天服务器通常采用常连接,亦有使用到短链的场景

◆ 协议的API规范(概要)

协议的实现原则:

■ 后端Server实现基本的、通用的功能,前端Server实现专用功能,降低系统的修改成本,提高开发效率。但若在各自的进程中实现各项功能,即使发生内存访问冲突时,也能防止包含相关功能的部分同时崩溃,Google
Chrome采用的多进程就是出于这种考虑

■ 前端Server依赖于后端Server结构,位于后端的Server先启动,前端Server后启动

■ 协议是无状态和简单操作的集合,C/S MMO中,复杂处理集中在gmsv,可将有状态的协议限制在client与gmsv之间,除了gmsv协议,若有其他协议需要有状态,一般都是不合理的设计

■ 尽量在一个地方接受外部的异常情况,数据的持久化在一个地方进行,易于维护

■ 优秀的API的调用时序:最上最优

● 不调用API,即不需要;能做到不调用其他接口最好

● 只调用没有返回值的API的单向时序图(图7-3)

● 只调用一次然后获取返回值的呈三角状的时序图(图7-4)

● 呈锯齿状的时序图(图7-5)

gmsv采用比线程更轻量级的回调和任务系统实现异步编程,当C/S
MMO中出现“锯齿状时序图”时就需要对其必要性重新加以讨论;在处理互斥机制的部分时,采用“三角状时序图”或“线状时序图”来实现

图7-3 单向时序图

 

图7-3 三角状时序图

图7-4 锯齿状时序图

 

■ 是否有必要Push

◆ 协议的API规范(详细)

◆ 网络数据包格式

八、 数据库设计

◆ 数据库设计图

◆ 编码前的重要的表的设计

◆ K-Online所需的表

◆ 数据库性能测试

九、 C/S + 中间件

◆ 网络游戏的中间件

◆ MMO的基础支持单元

十、 开发中的基本原则

◆ 编程之始,编程之续

◆ 数据结构优先原则

◆ 实现数据结构之前的讨论

◆ 维持可玩的状态的原则

◆ 后端服务器的延后原则

◆ 持续测定的原则

GThinkServerEngine

Server_Gate

◆ complie : 编译和生成protobuf协议相关及.C文件

◆ config_server : 服务器配置

◆ console_mgr : 输入管理

◆ logger : 日志模块

◆ utility_game : 服务器ID相关函数

◆ globals : 全局接口、common库头文件,服务器状态

◆ service_mgr : 服务管理

◆ service_client : 面向客户端的服务

◆ service_login : 登陆验证的服务(应考虑独立出来)

◆ service_game : 面向游戏逻辑服的服务

◆ handle_service_client : 处理客户端的网络消息

◆ handle_service_login : 处理登陆的网络消息

◆ handle_service_game : 处理逻辑服的网络消息

◆ handle_server_performance : 处理qps等性能提升

Server_Game

◆ complie : 编译和生成protobuf协议相关及.C文件

◆ config_server : 服务器配置

◆ console_mgr : 输入管理

◆ logger : 日志模块

◆ utility_game : 服务器ID相关函数

◆ globals : common库头文件和全局的接口

◆ server_pool : 服务器Socket连接池

◆ suffix_trie : 敏感词过滤、后缀树

◆ json_help : json格式转换

◆ user_data : 玩家所有基类数据节点

◆ user_extend : 玩家数据节点扩展

◆ csv_storage : .csv配置文件的打开关闭、读写操作

◆ mail_template : 邮件模版

◆ client_layer : 验证客户端网络包的合法性及会话状态是否建立

◆ client_message_object : 解析客户端消息Object的相关操作:解包[获取msgID、获取msgData
+ len、获取client session info]、打包,encode + 加密 [rspData]

◆ client_session : 客户端会话的定义和操作,包含客户端的上下线信息及定时扫描

◆ client_session_mgr : 客户端会话管理,使用循环队列管理会话信息

◆ message_listen : 消息监听

◆ notify_system : 游戏内的服务器主动推送系统

◆ oss : 运营日志

◆ rpc_call_db : rpc调用数据库

◆ service_game : 面向server_gate服务器的连接等管理

◆ service_game_handler : 处理客户端的网络消息

◆ service_login : 登录流程的验证服务

◆ service_mgr : 逻辑服务器本身的网络和服务的管理,例如,服务的创建、网络的状态

◆ service_tool : 逻辑服务器要管理提供的服务的工具,针对其网络层和服务状态

◆ user_finger : 逻辑服务器中的金手指功能

◆ base_object/

游戏节点数据缓存机制:

game_object ---> CMemObject : 内存对象类

game_object ---> CGameObject : 游戏节点类

game_object ---> CGameObjectT : 游戏节点模版类

game_objectsT ---> CGameObjectsT : 游戏节点模版s类1,重载

game_objects2T ---> CGameObjects2T : 游戏节点模版s类2,重载

rich_user ---> CRichUser : 游戏玩家类,包含玩家所有基类节点的增删查改等操作;玩家所有基类数据节点放在user_data中

rich_user ---> IUser : 玩家的功能接口

注意:基类Set和Get的接口,仅限于到下一层的信息,接口层次统一,其他具体获取可放具体模块逻辑中。

IGameObject:声明CGameObject、CRichUser

IGameObject---> IGameObject : virtualvoid Release( ) = 0;

IGameObject---> IGameObjectBuilder :

■ virtualCGameObject* BuildObject(pb_common::xxxInfo&
info ) = 0;

GameObjectBuilder ---> CGameObjectBuilder:声明玩家所有基类节点CBasexxx,

提供生成和获取GameObject的Builder接口;

■ static IGameObjectBuilder*Builder(){return m_builer;}

■ static voidBuilder(IGameObjectBuilder* builder){m_builder =builder;}

■ 数据成员:

IGameObjectBuilder* m_builder;

游戏基类数据节点:

user_data ---> CUserData : 存放玩家所有基类节点数据

rich_user ---> CRichUser : 包含玩家所有基类节点的操作(对应client_rich_user)

base_users ---> CBaseUsers : 声明了CUserData、CRichUser;提供的接口:

■ void Load() : 玩家数据加载

■ void Save() : 玩家数据保存

■ bool SafeUpdate() : 安全更新玩家数据

■ bool SynUserData() : 同步玩家数据

■ void EnumUser() : 遍历玩家数据

■ 数据成员 :

pb_common::DataCtrl m_ctrl;

map<USERID, RichUserSPtr> m_users;

base_user_mgrT --->CBaseUserMgrT : 按标志Flag加载玩家数据节点及更新玩家数据

base_role --->CBaseRole

base_army_tech --->CBaseArmyTech

base_army_tech --->CBaseArmyTechs

base_bag_item --->CBaseBagItem

base_bag_items --->CBaseBagItems

base_battle --->CBaseBattle

base_enemy --->CBaseEnemy

base_enemys --->CBaseEnemys

base_friend --->CBaseFriend

base_friends --->CBaseFriends

base_manor --->CBaseManor

base_plant --->CBasePlant

base_plants --->CBasePlants

base_quest --->CBaseQuest

base_quests --->CBaseQuests

base_suit --->CBaseSuit

base_suits --->CBaseSuits

等都是挂载在User节点下的,而User的做法是将数据放在CUserData类中,将数据的操作放在CRichUser类中

最终,玩家所有节点数据派生为以GameObject为父类的子类,并且以模版类GameObjectsT和GameObjects2T的形式存储在内存中,提供GameServer全局的数据访问和修改的接口IGameObject。

节点数据生命周期中的轨迹图:

◆ codec : 网络层数据设计:数据包格式、解包和打包方式、加解密方式等

网络包消息格式定义:

--------4--------8--------12-------16------20-------24--------28

|   |        |        |                |       
 | |

|- MsgHead -| userid |-   TokenBlob          -|
EncodeBlob|

|-                  MsgHeadClientRequest                   -|

MsgHeadClientRequest -- MsgHead - hdr_len4Byte

|         |

|         - hdr_msg 2Byte

-- session 4Byte

|

-- userid 4Byte

|

-- TokenBlob - org_len4Byte

|            |

|            - mode 1Byte

-- EncodeBlob - checksum4Byte

|

- reqid 8Byte

--------4---------8--------12-------16

|    |    |       |  |      |

|- MsgHead -|    |EncodeBlob |

|- MsgHeadClientResponse    -|

hdr_len 4Byte

hdr_msg 2Byte

result 2Byte

ogr_len 4Byte

mode   1Byte

◆ client_object/

client_game_object_builder--->CClientGameObjectBuilder

client_user_mgr --->CClientUserMgr

client_users --->CClientUsers

client_army_tech --->CClientArmyTech

client_army_techs --->CClientArmyTechs

client_bag_item --->CClientBagItem

client_bag_items --->CClientBagItems

client_battle --->CClientBattle

client_enemy --->CClientEnemy

client_enemys --->CClientEnemys

client_friend --->CClientFriend

client_friends --->CClientFriends

client_manor --->CClientManor

client_plant --->CClientPlant

client_plants --->CClientPlants

client_quest --->CClientQuest

client_quests --->CClientQuests

client_rich_user --->CClientRichUser

client_role --->CClientRole

client_suit --->CClientSuit

client_suits --->CClientSuits

Server_Redis_Cluster

Server_Redis_To_DB===>???(有没有更好的方法)

Server_Db_Cluster

Server_Common_DB ===>???(必要性)

Server_Login

Server_Auth

Server_Fight

Server_World

Server_Log

未完待续!待完善!转载必须附录原文地址:http://blog.csdn.net/itcombox/article/details/51445319

时间: 2024-10-13 22:45:47

MMO 游戏服务器引擎设计的相关文章

手机游戏服务器引擎Scut免费开源

scut 官网:http://www.scutgame.com/ Scut是一个开源.免费.稳定.快速开发的手机游戏服务器引擎,支持开发人员使用Python脚本语言或C#语言开发:底层采用C#编写,基于MVC框架思想设计, 开发人员只需要关注如何定义数据实体类及属性,不再需要关注多据库(MSSQL.MySql等)及表设计,Scut会帮助你自动检测生成相应数据库的表结构:它还提供了丰富的AIP和成熟的游戏模块中间件,快速开发你的游戏服务器应用,和Cocos2d-x完美结合,提供基于Cocos2d-

使用GoWorld游戏服务器引擎轻松实现分布式聊天服务器

GoWorld游戏服务器引擎简介 GoWorld是一款开源的分布式可扩展的游戏服务器引擎,使用Go语言(Golang)编写.它采用类似BigWorld的结构,使用了简化的场景-对象框架.以一个典型的MMORPG为例,每个服务器上会有多个场景,每个场景里可以包含多个对象,这些对象包括玩家.NPC.怪物等.GoWorld服务器可以将场景分配到在不同的进程甚至不同的机器上,从而使得游戏服务器的负载是可扩展的. 开源分布式游戏服务器引擎:https://github.com/xiaonanln/gowo

棋牌游戏服务器架构设计

转载自:简书一位同行的文章 一,棋牌类服务器的特点 1,棋牌类不分区不分服 一般来说,棋牌游戏都是不分区不分服的.所以棋牌类服务器要满足随着用户量的增加而扩展的需要. 2,房间模式 即在同一局游戏中就是在同一个房间中,同一个房间中的人可以接收到其他人的消息. 3,每个房间的操作必须是顺序性 这个特性类似与一般游戏的回合制,每个玩家的操作都是有顺序性的. 二,需要解决的技术点 1,数据共享 因为棋牌类游戏不分区不分服,我们在设计服务器的时候,是按世界服的思想去设计,即服务器是一个n多台物理机的集群

简论游戏服务器架构设计

一.QIPAI类服务器的特点 1,QIPAI类不分区不分服 一般来说,QIPAI游戏都是不分区不分服的.所以QIPAI类服务器要满足随着用户量的增加而扩展的需要. 2,房间模式 即在同一局游戏中就是在同一个房间中,同一个房间中的人可以接收到其他人的消息. 3,每个房间的操作必须是顺序性 这个特性类似与一般游戏的回合制,每个玩家的操作都是有顺序性的. 二,需要解决的技术点 1,数据共享 因为QIPAI类游戏不分区不分服,我们在设计服务器的时候,是按世界服的思想去设计,即服务器是一个n多台物理机的集

游戏服务器背包设计与实现

在游戏开发中,背包是一个非常重要的功能.几乎每个复杂点的游戏都会有背包的功能.不管是手游戏还是网页游戏,不管是SLG游戏,还是ARPG游戏,背包是必不可少的.背包的功能根据策划的要求,有的简单,有的复杂.以下我们就讨论一下几种游戏服务器背包的实现. 1,简单的游戏背包设计 简单的游戏背包到底简单到什么程度呢?那么这个游戏背包只是用来存放物品,不需要记录物品在背包中的位置,只需要记录物品的id和物品的数量即可.这样的游戏背包设计起来非常方便,在数据库中一个物品占一行即可,例如: 当获得物品的时候,

大型多人在线游戏服务器架构设计

由于大型多人在线游戏服务器理论上需要支持无限多的玩家,所以对服务器端是一个非常大的考验.服务器必须是安全的,可维护性高的,可伸缩性高的,可负载均衡的,支持高并发请求的.面对这些需求,我们在设计服务器的时候就需要慎重考虑,特别是架构的设计,如果前期设计不好,最后面临的很可能是重构. 一款游戏服务器的架构都是慢慢从小变大的,不可能一下子就上来一个完善的服务器构架,目前流行的说法是游戏先上线,再扩展.所以说我们在做架构的时候,一定要把底层的基础组件做好,方便以后扩展,但是刚开始的时候留出一些接口,并不

Scut游戏服务器引擎之Unity3d接入

[狗刨学习网] Scut提供Unity3d Sdk包,方便开发人员快速与Scut游戏服务器对接: 先看Unity3d示例如下: 启动Unity3d项目 打开Scutc.svnSDKUnity3dAssets目录下的TestScene.unity项目文件,选中Main Camera,将TestGUI.cs文件拖动到Inspector窗口的Script,如图: 点击运行,如下: 目录层次说明 1)       Net层:封装Http与Socket请求操作,以及网络协议的数据解析和请求参数的打包,其中

游戏服务器设计之NPC系统

游戏服务器设计之NPC系统 简介 NPC系统是游戏中非常重要的系统,设计的好坏很大程度上影响游戏的体验.NPC在游戏中有如下作用: 引导玩家体验游戏内容,一般游戏内有很多主线.支线任务,而任务的介绍.接取.领取奖励等操作都是通过NPC的操作,一般会有几个核心NPC,再不停的任务引导中,玩家会对核心npc印象深刻,强化了游戏代入感. 核心功能的展示和操作.游戏大部分功能都会放到游戏主界面,但是全部功能都放进去是不现实的,其他功能则以NPC的方式提供,比如进入某副本的入口等. 一些运营活动,比如道具

【前言】为什么要设计游戏服务器框架

设计游戏服务器框架: 项目设定周期:7月1日 - 12月31日 项目语言:PHP.Golang 项目成果: 1.PHP版游戏服务器框架 2.Golang版游戏服务器框架 设计目的: 1.挑战自己的毅力,遇到困难,勇敢面对解决 2.学习未涉及的领域和技术