serverBiatch / teamWiki

a team wiki for serverBiatches!
6 stars 0 forks source link

新跨服结构 #25

Open niepantzy opened 9 years ago

niepantzy commented 9 years ago

新跨服结构

新跨服的整体结构其实和现在挂机的逻辑服基本一致,也是依赖HawkUtil完成的架构搭建,所以在这里不再对HawkUtil做分析,@crazyjohn的share the wow's architecture已经很详细的介绍了底层结构。我这里主要对GlobalServer的架构从应用角度做一个分析,过程中会和GameServer做一些比对,算是一份比较琐碎偏使用说明的分析文档 PS:写完以后发现首先因为新跨服结构和GameServer基本一致,我们已经对原有的逻辑服有了充分的了解,然后新跨服属于刚刚搭建架构完成阶段,没有多少具体的业务,导致在文档中出现最多的就是和GameServer中的xxx相似--!


一、整体结构

先看类图: 这里选择了主要的几个包:

1.1:服务配置GlobalServerConfig(与GameServer中GsConfig相似) 主要就是一些服务相关的配置信息,比如serverId、port、platform等,用来做服务启动支持 1.2:全局服务GlobalServer(与GameServer中GsApp相似) 该类继承了底层HawkApp应用层封装了,主要进行的就是服务的初始化(包括网络初始化、线程池的初始化、数据库连接、对象管理区的初始化以及应用对象的创建)、协议进入应用层的过滤处理(目前这里主要对服务器注册协议进行了处理,类似于GsApp中对玩家登陆协议的预处理) 1.3:服务入口类GlobalServerApp(与GameServer中GsMain相似) 这个没什么多说的,就是创建GlobalServer对象并启动。

2、静态数据相关

2.1:业务层基础常量静态数据:GlobalServerBasicCfg(与GameServer中SysBasicCfg相似) 主要就是存储一些业务相关的常量信息,目前的代码中还没有使用到。 2.2:具体业务相关静态数据:MatchNpcCfg 代码中目前只有一个匹配机器人相关的静态数据配置。整体的使用方法与GameServer中config目录下的类一致。

3、数据库实体相关

这里主要就是数据库表的实体封装类,目前只有PlayerMatchEntity表,记录了玩家相关数据。

4、玩家相关

这里就一个类:GlobalPlayer,是一个队玩家信息的封装类,和GameServer中的PlayerData有相似的作用。

5、业务流程相关

5.1:服务器标识类:ServerIdentify(与GameServer中SysBasicCfg相似)

5.2:游戏服代理对象:GameServerAgent(与GameServer中Player相似)

这个代理对象会在一个GameServer连接跨服服务器时创建,与GameServer中玩家登陆创建player对象的流程相似。 主要字段是一个存储具体玩家GlobalPlayer对象的Map以及封装了一些与GameServer发送协议的方法:

/**
     * 发送协议
     * 
     * @param protocol
     * @return
     */
    @Override
    public boolean sendProtocol(HawkProtocol protocol) {
        if (protocol.getSize() >= 2048) {
            logger.info("send protocol size overflow, protocol: {}, size: {}", new Object[] {                   protocol.getType(), protocol.getSize() });
        }
        return super.sendProtocol(protocol);
    }
    @NotThreadSafeUnit
    public void clearTimeoutGuys() {
        for (Entry<Integer, GlobalPlayer> eachEntry : players.entrySet()) {
            if (eachEntry.getValue().isCacheTimeout()) {
                players.remove(eachEntry.getKey());
            }
        }
    }

    public GlobalPlayer queryPlayer(int playerId) {
        return players.get(playerId);
    }

    public Map<Integer, GlobalPlayer> getAllPlayers() {
        return Collections.unmodifiableMap(players);
    }

    public void addPlayer(int playerId, GlobalPlayer player) {
        this.players.put(playerId, player);
    }

    public ServerIdentify getIdentify() {
        return identify;
    }

5.4:游戏服代理模块基类:GameServerAgentModule(与GameServer中PlayerModule相似)

具体的与GameServer交互的业务逻辑模块都要继承这个基类,目前代码中的RandomMatchModule便是一个跨服匹配相关模块,主要的作用就是对网络协议进行业务处理。

5.5:管理器相关:xxxxManager(与GameServer中xxxxmanager相似)

每个业务模块都会有一个相关manager,主要处理一些抛送过来的系统内消息的业务处理以及全局相关逻辑。这里一般会出现并发,需要注意线程安全。

PS:完全说不下去啊。。。东西太少实在不知道怎么说了。下面说说具体的一个执行流程吧

二、整体时序

1、连接流程:

GameServer中的GlobalServerManager类在初始化完成后便会进入ontick驱动,每隔一段时间便会判断是否连接上了GlobalServer,如果没有连接。便会进行连接操作,连接成功后给GlobalServer发送注册协议。

2、协议发送流程:

这里以玩家发送匹配协议为例简述一下协议的发送流程:玩家协议在GameServer中的PlayerGSMatchModule中进行处理,判断如果GlobalServer已经连接,则通过GlobalServerManager将协议转发至GlobalServer,GlobalServer会在GameServerAgentModule相关子类中对该协议进行处理,如果业务有需要会抛内部消息给xxxManager相关类。最后xxxManager如果有消息需要通知到GameServer的话会发送协议过去,GlobalServerManager会对协议进行解析,然后将消息转发给具体玩家。。(这段写的更恶心。完全是流水,还不顺)

crazyjohn commented 9 years ago

有更深层次的思考吗?目前我们这么做的优缺点?

niepantzy commented 9 years ago

@crazyjohn 因为这个跨服框架和GameServer框架一致,所以不管是对新接触项目的开发人员还是对我们这些有经验的人来说学习上手成本都会大大降低,便于后面的迭代开发。同时该框架本身对项目的扩展有很好的支持。但是也是因为框架本身比较重,对这样一个只能说是重模块类的服来说就会有一些冗余,比如config相关就会有很多完全没必要的配置。同时这样一个跨服业务本身的数据存储量不是很大,如果每个跨服都维护一套数据库也会显得冗余,而且后面可能会有全服性的需求,不只是现在这种伪跨服,是不是用一个远端库来做统一的数据存储会更好一些。