服务器架构
- gateway进程:用于玩家连接登录和作为网关处理玩家socket信息和进程间rpc信息
- user进程:用于玩家游戏数据的保存,包括背包数据等,以及一些副本信息
- center:单服玩法,公会,竞技场,邮件,聊天
- map:副本,场景的战斗都在这。
- cross_gateway:用于路由,通常这个跨服网关进程上层有多个跨服节点,下层有多个单服节点,需要将上下层进程一一对应。
- cross_map, cross_center:跨服进程,用于活动等玩法。
- statistic:

进程间重连
单服进程
单服map,user,center是依赖单服gateway的,在启动的时候会监听退出事件(自己封装的)。进程间相互建立socket连接的时候会定时相互发送心跳包。
如果单服gateway退出进程,就会关闭所有socket连接,其他单服进程接超时收不到心跳包之后,认为socket断开连接。判断时候是gateway且是单服进程,满足条件就会发布退出事件,其他单服进程就会自动退出。
因为gateway是管理客户端连接的,如果gateway退出,那么其他单服也没有存在的必要,架构是这么设计。如果想要其他单服不退也可以,gateway退出之后其他单服需要把玩家登录信息清空,防止脏数据。
跨服进程
跨服进程不受单服影响,各个跨服进程不受单服gateway退出事件影响。进程退出之后,可以重新启动,然后从配置找到跨服节点的ip和port,重新建立tcp连接。
进程间连接
极端情况下两个进程几乎相同时间启动,然后读取配置的ip和port,向还没启动成功的进程建立连接,然后两个进程互相连接不上。
当进程启动的时候,肯定是先监听端口,然后再去发起tcp连接,不管怎样都是会有一个进程先监听端口完毕,先启动完毕的进程可能连接不上后启动完毕的进程,但是后启动完毕的进程一定能向前者发起连接。
某个进程主动连接另一个进程,如果连接不上,会定时检测,即定时创建tcp连接,直到连接成功为止。如果因为某些原因断开了,之后也是会定时检测然后主动连接
跨服活动开启通知方式
消息转发
项目协议事自己封装的,数据格式如下,即一个包头和内容。
| |
包头由几个核心字段组成:来源进程类型、来源进程编号,目的进程类型,目的进程编号。每个进程都是由进程类型,进程编号确定唯一性。
比如一个单服center类型,编号为3的进程,和跨服center类型,编号5的进程需要进行rpc通信:
在程序启动的时候单服所有进程都会链接单服网关,跨服进程连接跨服网关,网关与网关之间直连。
假设a, b进程需要相互连接,但a,b进程启动顺序不确定,假定a先启动,b后启动。过程就是类似tcp的三次握手
先启动的a进程必然无法主动连接b进程,所以b进程启动完毕会向a建立tcp连接,连接建立以后,然后向b进程发送一个rpc请求
当a进程收到请求之后,从包头获取
来源进程类型,来源进程编号,在本地注册a->b的连接信息,返回a进程的进程类型,进程编号给b进程b进程接收到返回信息之后,在本地以
进程类型,进程编号维护b->a的连接信息
消息发送a->b b->c异步问题
当进程主动发起tcp连接并连接成功之后,会发布一个连接成功事件,事件参数包含目的进程的类型、编号。
事件回调中,就是用来处理跨服活动开启的消息。当跨服开启活动了,如果单服进程连接了跨服,那么跨服就需要把活动信息广播给下面的单服,或者由单服主动拉取活动信息。这样才能保证多个进程数据一致。
现在有一个场景:如果跨服和单服不直接相连,而是中间有一个网关进程,即跨服连接网关,单服连接网关,跨服和单服信息rpc的时候是会先经过网关进程,然后转发到跨服进程。此时三个进程顺序不定启动,
- 如果跨服和单服先启动完毕,这样并不会出现问题,因为跨服和单服没有直接相连。
- 如果跨服和网关先启动完毕,由于跨服进程监听到网关进程连接,会把活动信息广播给网关,由网关转发给下面的单服,此时由于单服还没启动完毕,单服进程就无法收到广播信息。
- 如果单服和网关先启动完毕,由于单服监听到网关进程连接,会主动拉取活动信息,但是由于跨服还没连接到网关,因此无法将请求转发到跨服。
因此对于这种两个进程相互通信需要经过中间进程,且启动顺序不定的情况,需要实现由上级向下广播和下级向上请求的逻辑,才能保证数据正确获取。