天龙八部服务器端共享内存的设计(1/3)

一、服务器构架

一个天龙八部游戏区,主要服务器部署情况如下图所示:

实际部署可能有所不同。区角色数据库可以安装到Machine4,那么一个区有5台物理机器。LoginServer和WorldServer、CharacterDB、BillingServer有连接。WorldServer和各个GameServer有连接。ShareMemory和CharacterDB有连接。

一台物理机器上,会启动一个ShareMemory进程和一个服务器进程,服务器进程有世界服务器和游戏服务器。天龙八部的世界是ZoneBase的,一个游戏服务器服务启动多个线程,每个线程服务若干个场景。

在ShareMemory进程、WorldServer和GameServer进程,都需要对多种共享内存池进行初始化,初始化传入的类型是不同的,类型定义如下:

enum SMPOOL_TYPE

{

SMPT_SHAREMEM,

SMPT_SERVER,

SMPT_WORLD

};

共享内存池对象在ShareMemory进程中初始化时候,才会真正分配共享内存对象,并把池对象Attach到共享内存对象。在WorldServer和GameServer进程中,池对象只是获取共享内存对象并Attach。

天龙八部使用的共享内存对象有:

角色 SMUPool<HumanSMU> 类型ST_HUMAN_SMU

公会 SMUPool<GuildSMU> 类型ST_GUILD_SMU

邮件 SMUPool<MailSMU> 类型ST_MAIL_SMU

玩家商店 SMUPool<PlayerShopSM> 类型ST_PSHOP_SMU

道具序列号SMUPool<ItemSerialKeySMU> 类型ST_ITEMSERIAL_SMU

二、共享内存模块

几个关键的类和结构定义如下图:

ShareMemAO封装了系统共享内存API功能,提供了池对象Attach/Detach接口以及转储文件功能。

SMUPool模板类是具体的池对象,天龙八部实现的池类型有5种,具体数据类型对应5个结构:HumanSMU、GuildSMU、MailSMU、PlayerShopSM和ItemSerialKeySMU。

SMULogicManager模板类提供了对这些共享内存池对象进行管理的功能,如初始化、心跳、保存数据库、清理等操作。

三、ShareMemory进程中共享内存模块的主要功能

具体见ShareMemory.h/ShareMemory.cpp,该服务进程主要功能是:

根据配置创建共享内存池对象(SMUPool)和池管理对象(SMULogicManager);

对创建的内存池对象和池管理对象进行初始化,注意初始化传入的类型是SMPT_SHAREMEM;如果是这个类型,底层会分配具体的共享内存,而不是仅仅的Attach;

对共享内存池管理对象进行更新(心跳),会进行数据库存储等操作,这里是保存数据库的唯一地方。那么数据从数据库的加载是在哪里?下面会介绍,是在LonginServer进程里面。

关于数据库模块,顺带提一下,从代码看天龙居然用的还是ODBC接口,后来应该改了吧。

四、WorldServer中的共享内存池对象

具体见ShareMemManager.h/ShareMemManager.cpp。WorldServer中仅对两类池对象进行操作,他们是GuildSMU和MailSMU。

extern SMUPool<GuildSMU> g_GuildSMUPool;

extern SMUManager<GuildSMU> g_GuildSMUManager;

extern SMUPool<MailSMU> g_MailSMUPool;

extern SMUManager<MailSMU> g_MailSMUManager;

两个共享内存池对象的初始化在World.cpp的BOOL World::NewStaticManager( )函数中,注意此处传入的类型是SMPT_WORLD

五、GameServer中的共享内存池对象

具体见ShareMemManager.h/ShareMemManager.cpp。GameServer中对三类池对象进行操作,他们是HumanSMUPlayerShopSMItemSerialKeySMU

SMUPool<HumanSMU> g_HumanSMUPool;

SMUPool<PlayerShopSM> g_PlayerShopSMUPool;

SMUPool<ItemSerialKeySMU> g_ItemSerialSMUPool;

这些共享内存池对象的初始化在Server.cpp的BOOL Server::NewStaticManager( )函数中,注意此处传入的类型是SMPT_SERVER

原文地址:https://www.cnblogs.com/byfei/p/6389765.html