游戏开发论坛

 找回密码
 立即注册
搜索
查看: 13673|回复: 9

网关服务器与其他服务器之间的通信

[复制链接]

149

主题

4981

帖子

5033

积分

论坛元老

Rank: 8Rank: 8

积分
5033
QQ
发表于 2010-7-28 12:11:00 | 显示全部楼层 |阅读模式
不知道哪个博客网站比较好用,所以干脆就在论坛里发帖算了。

现在的网游一般是用一组服务器以一个整体对外提供服务,其中有些会与客户端有直接的TCP连接,有些则没有。常见的做法之一是设置专门的网关服务器,它负责与客户端保持TCP长连接,承担客户端与服务器组之间消息的中转功能。好处有:
只把网关服务器暴露给外网,
可以用多个网关服务器来分散负载,
服务器组内的其他服务器不用处理大量的网络连接(因此可以使用更简单的网络模块),
用户角色在服务器组内的不同服务器之间迁移时(例如切换地图或换线之类)可以不用断开和重新连接服务器……
首先我们假定一组服务器会拥有多个网关服务器,并且为了讨论方便我们只考虑地图服务器与网关的通信(以下把地图服务器简称为map,把网关服务器简称为gate。)。那么具体是怎样通信的呢?
在网络连接的角度看,有这么两种:
1.map与所有gate都建立网络连接。
2.map不与任何gate有直接的连接,而是在它们中间插入一个网关管理服务器(gateMgr),它作为一个中间层,所有gate与它连接,map也与它连接。
对于第二种,网络通信是这样的:
当map要向一组客户端发送消息时,它把目标客户端的某种id放进一个列表(比如sessionID、userID、playerID之类),然后把这个列表和需要发送的消息打包发给gateMgr。这里实际发出的相当于一个两层的消息,内层有一个将会由客户端收到的消息,然后这个加上列表就产生了实际由map发给gateMgr的消息。gateMgr需要分辨哪个客户端是归哪个gate管的,然后把带发送的消息分别发送给那些gate,发给各个gate的消息只有里面的目标客户端列表发生了变化,每个gate收到的列表里的客户端一定都是归它自己管的。反过来,客户端给服务器发消息就更简单了,当客户端消息到达gate后,gate会进行简单的检查和筛选(例如是不是个有效的消息、这段时间收到这个消息的频率是否太高),然后转发给gateMgr,gateMgr再把消息发送给需要收到它的服务器(例如行走消息会转发给map)。
对于第一种,map要发消息给客户端同样要生成目标客户端列表,然后和需要发送的消息一起发出去,但是有几种不同的做法:
1.map把所有目标填进列表,然后广播给所有的gate,每个gate收到后自己从目标列表中筛选出属于自己管理的客户端,然后进行转发
2.如果map给gate发的目标客户端id是运行期生成的sessionID,并且根据sessionID处于哪个ID段就能知道它属于哪个gate,那么map可以预先根据sessionID为相关的每个gate生成一个独立的消息,里面要转发的消息内容是一样的,但是目标列表是针对gate而生成的。
3.如果map给gate发的目标客户端id不是sessionID,而是userID、playerID这样的数据,那么就无法根据这些直接知道属于哪个gate,但是在玩家进入某map时,map可以知道这个玩家属于哪个gate,所以相当于在map内会记录每个玩家属于哪个gate,这样也可以向2一样发消息。
有gateMgr的方案里,map不用知道有多少个gate,想发消息了就直接发一个完事,很简单,唯一的缺点就是:消息多了一次中转,增加了延迟,但是这个延迟到底有多少需要测量,是否会影响到游戏也要看游戏策划的设计而定。
没有gateMgr的方案里,1会产生更多的网络消息,2和3都要求map知道要把消息交给哪些gate,一般一组服务器内不只有一个map,考虑到其他服务器如果也都用广播的方式,那么消息会增加很多,而如果要用2或3的方式,那么会让任何需要使用gate的服务的服务器都加入额外的复杂性。
从个人角度看,有gateMgr的方案是比较理想的,毕竟把“gate有多个”这一事实(及其带来的复杂性)都对其他服务器做了隔离,而代价只是消息多了一次中转而带来的延迟。只要是对延迟不敏感的游戏,gateMgr都是利大于弊的;对延迟敏感的游戏,最好也先测量一下再做选择。

0

主题

172

帖子

176

积分

注册会员

Rank: 2

积分
176
发表于 2010-7-28 21:45:00 | 显示全部楼层

Re:网关服务器与其他服务器之间的通信

忍不住回一贴。

其实可以gate之间P2P,gatemgr管理的是gate/map列表,并广播至各个gate上。

C2S/S2C消息包都带一个路径定位数据结构(例如“邮编/门牌/工号”),这样gate层直接就可以做到分发投递了。

走gatemgr中转会出现gatemgr负载价较高问题。

149

主题

4981

帖子

5033

积分

论坛元老

Rank: 8Rank: 8

积分
5033
QQ
 楼主| 发表于 2010-7-29 15:55:00 | 显示全部楼层

Re:网关服务器与其他服务器之间的通信

gate之间如果需要直接通信的话,可能只有私聊消息这种用途吧……不过我觉得这似乎会让gate的功能变得不再单一……
恩,只要有数据能够让gate分辨消息要发给哪些连接,那么把消息直接广播给所有gate是可以的,不过那样毕竟要让其他服务器与所有gate建立连接,个人觉得有点麻烦。
负载可能会集中于gateMgr,不过它的功能很单一,加上都是局域网的通信,应该还是有希望胜任的,当然实际要实验一下才能确定。

0

主题

172

帖子

176

积分

注册会员

Rank: 2

积分
176
发表于 2010-7-29 20:23:00 | 显示全部楼层

Re:网关服务器与其他服务器之间的通信

gate之间P2P的意义在于让gate正在变成消息的“路由”,消息是在“路由”间流动,最终发至目标map,这个和internet网络拓扑是类似的

消息包都带有具体路径,就不用广播了呀,好比说明是上海X街X号发出,上海分发中转站统一收货(发现目的地是到北京的,直接发给北京中转站),北京中转站接货,分发至北京X街X号。而2端的地址,可以是C,也可是S的一个map。

map和gate的连接?这个还不容易,开map的物理服务器各开一个gate,map直接本机通讯gate(socket/namedpipe/sharememory都可以)就可以了。

149

主题

4981

帖子

5033

积分

论坛元老

Rank: 8Rank: 8

积分
5033
QQ
 楼主| 发表于 2010-7-30 00:24:00 | 显示全部楼层

Re:网关服务器与其他服务器之间的通信

汗,我这里的gate是要能够与map等其他服务器分开来部署的,不过把网络模块独立为一个进程倒是符合我做的另一个东西:
http://bbs.gameres.com/showthread.asp?threadid=127994
XD

5

主题

37

帖子

166

积分

注册会员

Rank: 2

积分
166
发表于 2010-7-30 10:14:00 | 显示全部楼层

Re:网关服务器与其他服务器之间的通信

我怎么看都觉得 map和gate直连, 采用方法2简单
我们公司就是这样做的, 无非就是多1个 map而已, session_id , gate_id,你一个服务器才多少人?就算3000人循环这个map代价也该远小于mapMgr吧

gate间通讯?我再看看,听起来就复杂啊

5

主题

37

帖子

166

积分

注册会员

Rank: 2

积分
166
发表于 2010-7-30 10:25:00 | 显示全部楼层

Re:网关服务器与其他服务器之间的通信

看了下gate p2p
意思就是每个 MAP带一个或者几个MAP带一个GATE
相当于先投到自己 gate, gate间通过gate_id流动

这个,我总觉得与其加gate的上的消费, 还不如加gateMgr简单
不过这些都需要具体测,: )

149

主题

4981

帖子

5033

积分

论坛元老

Rank: 8Rank: 8

积分
5033
QQ
 楼主| 发表于 2010-7-30 10:57:00 | 显示全部楼层

Re:网关服务器与其他服务器之间的通信

如果gate只需要和map通信,那么gate和map直连也可以的,但是考虑到如果还有其他服务器也要和客户端通信,也都要和gate直连,那我感觉这个复杂性似乎扩散得到处都是,所以在性能允许的情况下我宁愿封装到gateMgr里。

0

主题

172

帖子

176

积分

注册会员

Rank: 2

积分
176
发表于 2010-7-30 20:57:00 | 显示全部楼层

Re:网关服务器与其他服务器之间的通信

所谓的P2P的Gate流程很简单,就是查看包目的地址(一般是个hash值),hashmap查找发送通道(map直连在本gate的直接发,远程gate的用目标P2P上行通道),发送。这流程无论C2S,C2G2C,S2C,S2S都通吃。gatemgr负责的就是更新维护hashmap,广播至各个gate。gate发现有新gate接入,就互相P2P连一下(我自己的P2P是TCP的双连接上下行通道分开模式),而gate往往走局域网确定了这个链接稳定高速。

gatemgr模式,你用到实际项目里吃到苦头就知道了~~~当几个服务大量广播发包时间恰好契合,阻塞累积后状态更加恶化,直接塞死gatemgr,全服瘫痪。(例如我自己做的实际项目,有个地方需要给远程服务大量发送日志记录,当碰到恰好有其他高流量需求通信,造成消息大量拥塞,然后开始有人掉线了,再然后,掉线的尝试登录,更加大数据包流量,再再然后...)

再说类比清楚点
gatemgr = 邮政部
gate = 各地邮政局
c/s = 具体地址
邮政体系中需要把货物全部发到邮政部统一分发么?不需要。它安排邮编即可。
各地邮局间直接联系很困难?不,他们各自都有唯一ID的邮编及联系方式,直接发送很简单(还可以打包批量发,看速度要求)。
各收发货地址间收发很困难?不,他知道发送地就行,邮政局会把东西交给最清楚对方详细地址的收取点邮政局,对方邮政局会交到对方手上。


题外话,这套gate系统,已经实践过3年多了。该模式带来的极大优势,是一个socket连接,访问全服所有服务,且服务可以快速换服务器开(如事先准备好,几秒内完成迁移),其他服务完全不用重新配置。访问各个服务基本是以“域名”的模式,不用关心具体什么IP。

149

主题

4981

帖子

5033

积分

论坛元老

Rank: 8Rank: 8

积分
5033
QQ
 楼主| 发表于 2010-8-1 20:02:00 | 显示全部楼层

Re:网关服务器与其他服务器之间的通信

我倾向于用gateMgr的原因之一就是为了避免自己再去做动态路由维护,因为觉得这是个本来已经在底层解决了的问题,在这里不应该重复出现这样的问题的。

“当几个服务大量广播发包时间恰好契合”
如果你这里是说服务器广播消息给客户端的话,如果gate提供了广播服务,那么某个服务器需要广播时只需要把要广播的消息发送一份,在这个消息前面会添加一个目标id,这样实际上发送的还只是一个消息。那么我想相对于不是广播的情况来说应该不会产生太大的压力。即使gateMgr转发给gate,只要gate知道这个消息应该转发给哪些gate,那么消息数量也很少,因为只有相关的那些gate才需要收到消息,并且每个gate也只需要收到一个消息(消息前面仍然会是目标id列表),这时产生的消息数量最多最多就两位数,我甚至认为大多数情况下一个广播消息涉及的gate数量会是个位数。
你举的例子,如果是要给远程服务器发送日志,我觉得这个似乎没必要从gateMgr走。至少我对gate和gateMgr的定位就是用来客户端和服务器通信的。

我现在一直希望能够把gate这套机制做得更简单一些。特别是如果需要自己做动态路由表的维护的话,我觉得是种重复建设,我想尽力避免做得太复杂。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-6-8 06:20

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表