如何提高服务器利用率(棋牌游戏)

158 views
Skip to first unread message

lamputa

unread,
Nov 6, 2007, 2:08:23 AM11/6/07
to 高性能网络编程邮件列表
我们很常玩游戏的时候都知道,有的房间人满为患,有的房间空无几人,一般来说,玩家都喜欢去人多的房间玩,因为这样更容易让大家进入游戏,也有更多的游
戏机会,所以上述的情况还是时常发生的。
下面以QQ GAME的棋牌游戏为说明例子。首先我们假设对QQ Game的系统架构有一个共同的认识,当然这个架构不一定就是QQ的真实架构,这个架
构是从大宝的讨论中来的。我想即使有很多不同,但是也会有一定的相同点的。下面是引用,想参与讨论的朋友可以先阅读这篇文章。
http://blog.csdn.net/freexploit/archive/2005/09/02/469972.aspx

好了,我们的共同认识是一台服务器可以承担几个房间的服务,比如服务器1承担了房间1~5的服务,服务器2承担了房间5~10的服务,那么当上面提出的
问题发生的时候怎么办呢,比如房间1~5用户爆满,而房间5~10房间的人都很空,造成的结果就是服务器1很繁忙,那么房间1~5的服务速度肯定相对比
较慢的,虽然这个值是我们系统确认的可以基本接受的速度,但是这个速度肯定不是我们所能满意的,因为我们的服务器2非常空闲,如果可以把服务器2的计算
能力分轻服务器1的能力,那是非常好的,因为这种不均衡的状况是时时存在的,大家留意一下就知道,而且我们通常没有办法在系统运行之前就能确定哪个房间
人多哪个房间人少。
那么怎么解决这个问题呢,首先想到的是将服务器1和服务器2所服务的房间号尽可能打散,比如服务器1服务1,3,5,7,9房间,服务器2负担
2,4,6,8,10房间,这样划分一定程度上是可以收到效果的,因为一般来说玩家拥挤的房间都是排在前面的,但是即使是这样划分,我们心里也没有多少
底,因为我们不能够保证就不会发生上面提到的问题。
第二个方法是动态的数据迁移,就是说如果一台服务器发现自己的负担明显重要其他服务器,那么就动态的把其中一个房间跟另一个服务器的房间对换,比如服务
器1的重负荷房间1与服务器2的轻负荷房间4对换,对换之后服务器1管理房间4,服务器2管理房间1,但是数据的迁移是会出问题的,因为这个迁移要对玩
家进行透明,而每个玩家跟服务器之间的数据交换是很频繁的,要进行迁移,很难做到无缝透明,而且迁移之后,玩家的连接也要从服务器1转移到服务器4,或
者从服务器4转到服务器1,由于有一个房间是很满人的,所以这个开销也是不小的。
这里要考虑的一个比较重要的问题就是每一个玩家看到的信息都是以房间为单位的,而这个数据又是要求实时处理的。不知道各位有什么好的方法可以处理这个问

egg

unread,
Nov 6, 2007, 4:32:25 AM11/6/07
to 高性能网络编程邮件列表
迁移是把玩家从房间1移动到房间2还是2个服务器同时服务房间1呢?

绝对零度

unread,
Nov 6, 2007, 4:29:38 AM11/6/07
to 高性能网络编程邮件列表
这个不就是并行计算嘛?我知道Linux的系统支持集群计算的,不过好像有专门的函数库,我没研究过,只能建议你朝这个方向找找资料

lamputa

unread,
Nov 6, 2007, 5:48:06 AM11/6/07
to 高性能网络编程邮件列表
这里的迁移是指房间互换,也就是把人满的房间从负担重的服务器迁到负担轻的服务器,把人少的房间从负担轻的服务器迁移到负担重的服务器

On 11月6日, 下午5时32分, egg <egg.t...@gmail.com> wrote:
> 迁移是把玩家从房间1移动到房间2还是2个服务器同时服务房间1呢?

lamputa

unread,
Nov 6, 2007, 5:56:19 AM11/6/07
to 高性能网络编程邮件列表
并行的概念很广泛的,如果有想法,请把你的想法表达清楚。
并行有并行的概念,但是这里是受到应用环境影响的。第一,从服务器的角度来说,需要达到最高的效率,必须是让玩家直接连接到为他提供直接服务的服务器
上,而不需要经过转发。第二,存在一个粒度的问题,在这里,是以一桌为单位的,为什么这样,是因为玩家需要即时了解整个房间的座位情况,而这个数据即时
性要求很高的,所以不宜经过转发或者分散处理再汇聚。

> > 题- 隐藏被引用文字 -
>
> - 显示引用的文字 -

Linker M Lin

unread,
Nov 6, 2007, 8:58:00 PM11/6/07
to 高性能网络编程邮件列表
与其移动房间不如在用户选择房间时,推荐用户进入半满的房间.
这样只要修改下客户端,就搞定了,
简单就是美~

zcpro

unread,
Nov 6, 2007, 9:09:56 PM11/6/07
to 高性能网络编程邮件列表
由于国内网络的特殊性,转发是不可避免的,网通和电信用户想在同一个房间玩,同时要保证双方的网速怎么办,所以只能转发。
估计qq也是这么实现的,进入房间后连接的其实是转发服务器,游戏逻辑服务器应该在内网。

lylone

unread,
Nov 6, 2007, 10:03:57 PM11/6/07
to 高性能网络编程邮件列表
同意zcpro的看法,如果把转发服务器叫做Memory Cache服务器,相信更有助于楼主的理解。

我的想法是这样的,1-100号房间其实位于某一台Memory Cache上,而房间中的每台桌子才真正与业务服务器相关联,如此一来,一个房间中的
不同桌子,实际上是位于不同的节点服务器上的。利用这种方法,非常容易地把拥挤房间的用户分散到闲散的节点业务服务器上去进行游戏。而刚好房间这个概
念,本来就是适用于Memory Cache这种性质的服务器。

这种方案,就无需去考虑什么房间迁移了。房间所在的Memory Cache服务器,既可以帮助用户建立联系,也可以进行节点服务器的负载均衡,还可以
进行控制数据的转发工作。

一台Memory Cache服务器(房间)配合N台业务服务器(桌子),组成了一个大的节点,逻辑上就是单独的一层架构。

lamputa

unread,
Nov 7, 2007, 1:24:11 AM11/7/07
to 高性能网络编程邮件列表
你说的方法我也考虑过,就是服务粒度是以桌为单位,而不是以房间为单位,这样做可以桌的粒度上做均衡,但是由于转发,效率会大大的打折扣。试想一下,同
一个房间的人,他必须是要知道同一个房间里面的桌位信息(看哪里有空位子,哪里有人),而且这个数据必须是即时的,按照你的设计,试想一下服务器与
Memory Cache之间的数据量将是一个降低服务性能的新问题。
至于电信与网通之间的问题,确实存在,之前我没考虑过同一个房间内出现这个问题。这个问题不知道能不能在服务器上装上双网卡,一个连接电信用户,一个连
接联通用户解决,没做过这样的事情,不知可否。

> > > > - 显示引用的文字 -- 隐藏被引用文字 -
>
> - 显示引用的文字 -

stamilo

unread,
Nov 7, 2007, 1:42:37 AM11/7/07
to dev4s...@googlegroups.com
lylone 的方法其实很好, 
    我们将 Memory Cache看作经理, 将业务服务器看作 worker,
       经理做得只是联系工作, cpu负载轻,网络负载重;
       worker 相反,cpu负载重,网络负载轻, 作主要的业务逻辑(聊天、棋牌逻辑。。。),
    这样,worker的工作可以独立出来,做并行计算。

    网络游戏,接入服务器和业务服务器的划分相信大家都能接受,接入服务器的负载均衡相信大家也能做到,而业务服务器的负载均衡才是重点,通过并行计算应该是个很好的解决方法。

   还有,不要局限于房间和桌子,他捆住了你的手脚,让你在规划上就限制了服务器。

sunway

unread,
Nov 7, 2007, 1:45:31 AM11/7/07
to 高性能网络编程邮件列表
吹吧,高屋建瓴的吹吧。

On 11月7日, 下午2时42分, stamilo <stam...@gmail.com> wrote:
> lylone 的方法其实很好,
> 我们将 Memory Cache看作经理, 将业务服务器看作 worker,
> 经理做得只是联系工作, cpu负载轻,网络负载重;
> worker 相反,cpu负载重,网络负载轻, 作主要的业务逻辑(聊天、棋牌逻辑。。。),
> 这样,worker的工作可以独立出来,做并行计算。
>
> 网络游戏,接入服务器和业务服务器的划分相信大家都能接受,接入服务器的负载均衡相信大家也能做到,而业务服务器的负载均衡才是重点,通过并行计算应该是个很好 的解决方法。
>
> 还有,不要局限于房间和桌子,他捆住了你的手脚,让你在规划上就限制了服务器。
>

lylone

unread,
Nov 7, 2007, 1:47:26 AM11/7/07
to 高性能网络编程邮件列表
你还是没有明白我的意思,我之所以叫房间服务器为Memory Cache,就是因为房间服务器缓存着玩家数据。当一个玩家坐下一个空桌子时,房间就给
这张桌子预分配了一台空闲的业务服务器,该玩家就连接上了该业务服务器,其他玩家再坐下时,房间服务器自然会通知他们应该连接哪台业务服务器,当桌子上
的玩家齐全后,游戏开始时,则全部由业务服务器来处理。

对于房间服务器而言,他已经拥有这些玩家的状态信息,谁在几号桌,几号桌开始了游戏,哪些玩家被分配到了哪台业务服务器,这些都是业务服务器牵线搭桥
的,他有记录,根本不需要向业务服务器沟通查询!

只有在玩家离开桌子时,业务服务器才需要通知一下房间服务器,改变玩家的状态,如果整张桌子的玩家全部离开,那么该桌号就跟原先的业务服务器脱离关系,
下次再分配时,就重新根据房间服务器的负载计数来重新安排业务服务器。房间服务器跟业务服务器唯一的数据交流,只有在玩家离开桌子的时候才会发生。

根据一个房间400个用户来算,这样一台房间服务器,可以部署10-50个房间。所以,我才把房间服务器叫做Memory Cache服务器。

lylone

unread,
Nov 7, 2007, 2:08:00 AM11/7/07
to 高性能网络编程邮件列表
笔误,应该是房间服务器牵线搭桥,这些数据都在房间服务器的内存中。

采用这样的架构,所谓的房间拥挤,只是一种假象而已,实际上,某些房间的所有用户都在同一台房间服务器上,而真正的游戏,又是分布到业务服务器上进行
的。

lamputa

unread,
Nov 7, 2007, 3:07:12 AM11/7/07
to 高性能网络编程邮件列表
首先感谢各位的关注和讨论!
lylone,我明白你的意思,不过我觉得你的方案没有解决提出的问题,只是把问题转化到前面的Memory Cache中,而且增加了转发的负担。
让我们再仔细点的讨论里面存在的问题。(这里不能贴图,有点不方便)

WS1(房1桌1) WS2(房1桌2) WS3(房1桌3)


CS1(电信)(房1) CS2(网通)(房1) CS3(电信)(房2)

c1 c2 c3 c4 c6 c7

上图中我没有画出连线,用字符画线太难了。解析一下,WS1--WS3就是所谓的逻辑服务器,用来处理桌子逻辑的,CS1--CS3就是你模型中的
Memory Cache,c1--c4是电信用户,连接到CS1, C6~C7是网通用户,连接到CS2,假设他们都是在房间1玩游戏,而由于有网通
和电信之分,所以房间1需要分配在CS1和CS2上,也就是说,CS1和CS2共同负责房间1的连接并且维护房间1的座位状态。
好了,现在假设C1~C7分散在桌1~3中,对应于WS1~WS3为他们服务,想象一下。
桌1的人员变动,那么WS1必须向CS1,CS2发送消息,通知其座位情况的变化,而CS1,CS2又必须发送消息给连接到其上面的所有房间1的玩家,
座位变化。而且所有WS与玩家的信息都是经过CS服务器转发的。由于转发,CS的网络流量几乎增加了1倍,所以CS很可能成为瓶颈。
还有一个问题,就是这个方案并没有解决最初的问题,就是房间1人数爆满,但是房间2空人,所以CS1,CS2很忙,CS3基本没有负担,所以,只是把问
题从WS转移到CS上面。

lylone

unread,
Nov 7, 2007, 3:35:56 AM11/7/07
to 高性能网络编程邮件列表
你的思路开始混乱了!首先,站在服务器层面上,你是不需要去考虑网通和电信这线路问题的。为什么呢,一台服务器,两张网卡,一个接入电信,一个接入网
通,每个网卡都有自己的IP,对于客户端来说,他们可以主动选择电信和网通来登录,也可以在客户端帮其自动判断,对应不同的网通IP和电信IP接入,如
此一来,只是登录IP不同,而实际连接的都是同一个服务器。

忽略了这一层因素,再来看用户的接入。为方便描述,我统一把Memory Cache服务器这种说法转换为你所说的cs服务器,而业务服务器转换为你的
ws服务器。

再来看,一台cs服务器搭配8台ws服务器形成了一个逻辑上的大节点,其中cs服务器上部署了20个房间。客户c1-c400分别进入了房间1,也就是
接入了cs服务器,cs服务器会根据负载把这100桌玩家平均分配到8台ws服务器上,从401个玩家开始,他们只能进入房间2、3、4...,实际上
依然在该cs服务器上,由cs服务器来继续分配到8台ws服务器上进行游戏。

现在你来具体地告诉我,cs服务器究竟有哪些转发负担?至于你说的20个房间后的cs2空闲问题,我们稍候再讨论,这种情况确实存在的,但依然有解决方
案,解决方法就是把房间这个概念给抽象化,但最终还是以我这个架构为基础来扩展。

lamputa 写道:

zcpro

unread,
Nov 7, 2007, 3:41:37 AM11/7/07
to 高性能网络编程邮件列表
转发(cache)服务器不能修改玩家的状态,只做转发,这样转发服务器之间就不需要通信了。也就是按lylone的方案必须再加一层
玩家--转发(无状态,可以是电信网通双线服务器)--房间服务器--游戏逻辑服务器。
转发的性能其实不用过于担心,由于服务器之间一般是通过局域网连接的,带宽没有问题,延迟在10ms以下。
还有这个服务器架构中负担最重的一定是游戏逻辑服务器,房间服务器人数不均衡关系不大。估计转发服务器的承载能力在几万人,观察一下qq游戏里一个区
2,3万人的规模,估计实现思路是差不多的,人满了多开几个区就可以了。
如果不怕实现麻烦还可以再优化一下这个架构,如果房间服务器放在电信,电信用户就直连该房间服务器,只有网通用户才转发。

lamputa

unread,
Nov 7, 2007, 3:54:36 AM11/7/07
to 高性能网络编程邮件列表
很好,谢谢你的回复。你说的通过双网卡屏蔽掉电信和网通的问题,这点也正是我上面提出的问题,我们现在就屏蔽掉这个问题,不去区分。
1。先确认一点,按照你的方法,确实是可以让WS可以得到比较好的均衡。
2。新的构架遇到新的问题,这点你也提到了,如下:
至于你说的20个房间后的cs2空闲问题,我们稍候再讨论,这种情况确实存在的
=====================================
我认为这个问题是矛盾的转换,即把WS的矛盾转化到CS,希望有好的解决方法
3。关于转发问题,主要存在于WS的任何消息(包括进和出),都是通过CS转发的。我们把玩家的消息分为两类,一类是玩牌消息,另一类是位置变化消息,
这两类信息都是要经过CS转发给WS的。对于玩牌消息,是从C--》CS--》ws(得到结果)--》CS--》C , 对于位置变化消息是C
--》cs--》ws , 所以转发的带来的信息量也是可量的

下面谈谈我的想法,你的构架本来是想把WS独立开来,以达到负载均衡的目的,但是WS所承担的工作量比例相对比较小(只是牌的逻辑计算,没有太多网络负
荷以及处理量要求比较大的房间位置信息),所以,导致前面的CS工作量比较重,但是现在来看还没有做负载平衡,后面的WS工作量比较轻,但是做了负载平
衡。


anyway,很感谢你的讨论,希望能继续。

> > > > > > > > > > 问题发生的时候怎么办呢,比如房间1~5用户爆满,而房间5~10房间的人都很空,造成的结果就是服务器1很繁忙,那么房间1~5的服务速度肯定相对比- 隐藏被引用文字 -
>
> - 显示引用的文字 -...
>
> 阅读更多

lylone

unread,
Nov 7, 2007, 4:10:52 AM11/7/07
to 高性能网络编程邮件列表
你确实没有真正理解我的意思,我说过,从游戏开始后,也就是客户端坐上桌子开始,所有工作全部交付给ws服务器进行的,而cs只是把状态记录下来(玩家
c1坐在第xx号桌,准备游戏)。也就是说,游戏中,所有的交互是ws和客户端直接进行的,与cs无关,只有游戏结束跟玩家离开桌子(正常退出或者掉
线)时,ws才会把这一状态通知cs,由cs对这些玩家状态进行改变(所以我叫cs为Memory Cache)。

现在,对这个架构还有什么问题么?如果没有,我们可以继续说下一个问题,就是怎样也让cs得到负载均衡。

> ...
>
> 阅读更多

lamputa

unread,
Nov 7, 2007, 4:12:15 AM11/7/07
to 高性能网络编程邮件列表
看了zcpro的回复,得到两点信息,转发在内网中,效率不需要太担心。以及游戏逻辑服务器的负担问题,想想也不至于如我想的那么轻,想想每一桌中都需
要记录当前玩家的状态,以及处理当前游戏的逻辑,还是有一定的工作量的。
基于这两点,按照lylone的方案,确实可以提高效率。
但是如何让CS层也具有负载均衡呢,不至于由于玩家选择房间的失衡而导致系统某部分负担过重而出现的效率问题,这个其实是最初提出的问题,只不过最初是
出现在没有分离的WS服务器上,现在出现在CS服务器上。

> > > > > > > > > > 那么怎么解决这个问题呢,首先想到的是将服务器1和服务器2所服务的房间号尽可能打散,比如服务器1服务1,3,5,7,9房间,服务器2负担- 隐藏被引用文字 -
>
> - 显示引用的文字 -...
>
> 阅读更多

lamputa

unread,
Nov 7, 2007, 4:19:37 AM11/7/07
to 高性能网络编程邮件列表
噢,确实误会了,我没有想到你是让客户与WS直接连接,让我来解析为什么没有这么想,因为这样的话,一个客户必须要跟他的WS保持长连接,也必须与CS
保持长连接(因为位置变化的信息也必须是实时的),所以一个客户必须与我们的服务器保持两个长连接。这个是我想规避的问题,在大宝的那篇文章里,也提到
过这个问题,就是进入房间后只有一个连接被创建。
对了,我对你的cs负载均衡方案也很感兴趣。请继续,thanks。
也希望能得到更多人的参与,thanks。

> > > > > > > > > 由于国内网络的特殊性,转发是不可避免的,网通和电信用户想在同一个房间玩,同时要保证双方的网速怎么办,所以只能转发。- 隐藏被引用文字 -
>
> - 显示引用的文字 -...
>
> 阅读更多

lamputa

unread,
Nov 7, 2007, 4:25:49 AM11/7/07
to 高性能网络编程邮件列表
lylone,你继续说,我希望把你的所有想法都说出来后我再做评论,这样可能更好。等你说完了你的想法,我们再讨论。

On 11月7日, 下午5时10分, lylone <Lias....@gmail.com> wrote:

> > > > > > > > > 由于国内网络的特殊性,转发是不可避免的,网通和电信用户想在同一个房间玩,同时要保证双方的网速怎么办,所以只能转发。- 隐藏被引用文字 -
>
> - 显示引用的文字 -...
>
> 阅读更多

lylone

unread,
Nov 7, 2007, 6:27:04 AM11/7/07
to 高性能网络编程邮件列表
刚才下班了。如果对这个架构没问题的话,现在继续说cs服务器的负载均衡控制。

如果从技术角度来解决这个问题,我只有一个理论的方案,关键还是分布,主要是增加了一些散列算法用以精确定位,从而提高性能,这个方案就不谈了,因为缺
乏实际应用。

我说一下策略上的解决方案,以我之前提出的架构为基础,由cs服务器的更上一层服务器来动态控制房间数目。按照我的架构,一台cs搭载一定数量的ws服
务器,按照一个房间400用户计算,整个节点维持20-50个房间不成问题。那么如果你有四个该服务器集群,你可以在上层服务器上首先创建4个房间,这
四个房间分布在这四个集群上,而后采用动态生成房间,当房间剩余减少到一定数量时,从四个集群中选择最空闲(房间数目最少的)的那个集群,增开一个新的
房间。相反,如果剩余房间很多,就回收。(这种回收也就是合并,跟同一台cs服务器上的其他房间合并,从编程角度来讲,甚至只是一个内存标志位的改变。
玩家可能觉得是在13号房间,事实上13号房间已经不存在,被1号房间合并了,他正与1号房间的用户进行游戏)

采取这种分布式思想,就轻易地解决了cs负载均衡的问题。就像我说的,房间号是个抽象的概念,它跟桌号一样,也不是固定在哪个服务器机群上,而是动态分
布。

lylone

unread,
Nov 7, 2007, 6:45:19 AM11/7/07
to 高性能网络编程邮件列表
客户只有进行游戏时才与ws服务器保持连接,离开桌子后就断开了。对于客户端而言,他根本不知道有哪些ws服务器,他需要的ws服务器IP都是cs服务
器反馈给客户端的。

对客户端而言,保持几个连接并不需要特意去规避,这个不重要。

> ...
>
> 阅读更多

lamputa

unread,
Nov 7, 2007, 8:21:14 AM11/7/07
to 高性能网络编程邮件列表
我想这种做法有点问题,我们需要考虑实际的情况。可能这个要先从玩家登陆系统开始说起。大概的过程是玩家登陆系统,然后从登陆服务器中取得一份游戏目
录,记录有什么游戏,每个游戏有多少个房间,每个房间的IP以及每个房间的人数等数据。我想玩过QQ GAME之类的游戏都有这样的使用经验。用户拿到
这份信息后,之后只会根据这份信息找到房间所对应的IP,也就是说房间已IP是已经绑定的,房间数量也是相对固定的。如果房间与IP之间的对应关系是动
态变化的,玩家就会感觉混乱,比如约了朋友到某个房间玩,怎么办?如果房间是动态生成的,那么前面登陆的用户与后面登陆的用户看到我们的服务目录也是不
同的。其次,关于合并的问题,如果你在一个房间玩游戏,本来房间是比较空的忽然之间合并了,一下房间满了很多人,玩家不觉得奇怪?虽然底层怎么实现玩家
不用理会,但是我们需要给玩家呈现一个切合实际的环境,让他们看到的东西跟现实生活中的概念是类似的。

再来说客户的连接数问题,对于客户来说,多几个连接问题都不大,但是对于服务器,如果从一个连接变为两个连接,就连接数而言,似乎也增加了一倍,如果我
们的系统是以大型系统来考虑,也是一个相当客观的资源。

或者我们回头来看看我最初提出来的问题,那个方案似乎只是没有解决房间的失衡问题,其他方面似乎问题不大,不知道基于这个基础,有没有更好的想法。

Linker M Lin

unread,
Nov 7, 2007, 8:14:07 PM11/7/07
to 高性能网络编程邮件列表
这是典型的简单问题复杂化.
不就是想让服务器负载平均化么...
鼓励玩家进入半满的房间就可以很简单的解决这个问题.
比如,进入服务器推荐房间可以奖励一些经验值...

还是那句话,简单就是美~
成本和用户体验优先~

lylone

unread,
Nov 7, 2007, 8:58:56 PM11/7/07
to 高性能网络编程邮件列表
我只是提供一个思路,回收机制你可以不采用,直到最后一个玩家离开房间再把房间给回收也可以,动态生成房间来负载均衡,这种机制在浩方平台上就是这样
的。

至于客户端要有几个连接,这种问题根本不用考虑的。玩过QQ游戏的都知道,玩家同时进三四个房间那是常有的事情,更何况业务服务器和房间服务器是分开
的,跟两者各保持一个连接不是更正常吗。

实际上房间服务器的实时性没有你想象的那么高,他只是在玩家数据的同步上需要更高的实时性,尽量减少对用户数据库的查询,避免引起数据库的瓶颈。而在网
络上没有那么高的实时性,所以我更愿意叫它Memory cache服务器,如果你用UDP来构建房间服务器,一台服务器开50个房间以上还是很轻松
的。

我没注意过QQ游戏,估计他的一个区也就是100个房间,基本上一个区就是一个集群。

如果你把房间服务器和游戏服务器架构在一起,一台服务器也就能开10个房间,这样的架构首先不利于扩展,棋牌类游戏种类很多,你是不是每种类型的都需要
附带一个大同小异的房间服务器功能?不同类型游戏的房间服务器,都是单独定制的话,在用户数据和通信协议上会有什么问题,服务器的增量部署是否很容易实
现,这些你都有了详细的方案了吗?

你有想的更细致一些么?在用户数据上的同步,第二层节点也就是房间服务器,是需要跟用户数据库交互的(玩家积分之类的数据),第二层的节点数量越多,这
种同步交互就越复杂越频繁,带来的问题更多。你的架构基本上没有考虑用户数据的同步问题,把所有工作都交给了数据库,也把数据库当成了无限制无瓶颈的资
源。

分布式服务器的三层架构,为什么要分层,每层的目的是什么,只有真正弄清楚这些,才能举一反三,架构出自己的服务器。

lamputa 写道:

Lethean

unread,
Nov 7, 2007, 9:13:47 PM11/7/07
to dev4server
dev4server,你好
 
    好像提出了好几个问题混杂在一起。还是分开说比较好:)
1.负载均衡,在非峰值状态,每台游戏服务器都不要满负载状态工作。比如说原来一台游戏服务器满负载可以支持20个房间,非峰值状态下,只开启15个房间。随着用户数量增加,逐渐开启新的房间。
2.南北互通,双线机房或者采用gateway server都可以解决。
3.服务器架构,房间内的逻辑处理与游戏逻辑耦合性很强,最好不要分开。
 
 
 
 
2007-11-08
----- Original Message -----
From: lamputa
Sent: 2007-11-06, 15:08:23
Subject: 如何提高服务器利用率(棋牌游戏)

我们很常玩游戏的时候都知道,有的房间人满为患,有的房间空无几人,一般来说,玩家都喜欢去人多的房间玩,因为这样更容易让大家进入游戏,也有更多的游
戏机会,所以上述的情况还是时常发生的。
下面以QQ GAME的棋牌游戏为说明例子。首先我们假设对QQ Game的系统架构有一个共同的认识,当然这个架构不一定就是QQ的真实架构,这个架
构是从大宝的讨论中来的。我想即使有很多不同,但是也会有一定的相同点的。下面是引用,想参与讨论的朋友可以先阅读这篇文章。
http://blog.csdn.net/freexploit/archive/2005/09/02/469972.aspx

好了,我们的共同认识是一台服务器可以承担几个房间的服务,比如服务器1承担了房间1~5的服务,服务器2承担了房间5~10的服务,那么当上面提出的
问题发生的时候怎么办呢,比如房间1~5用户爆满,而房间5~10房间的人都很空,造成的结果就是服务器1很繁忙,那么房间1~5的服务速度肯定相对比
较慢的,虽然这个值是我们系统确认的可以基本接受的速度,但是这个速度肯定不是我们所能满意的,因为我们的服务器2非常空闲,如果可以把服务器2的计算
能力分轻服务器1的能力,那是非常好的,因为这种不均衡的状况是时时存在的,大家留意一下就知道,而且我们通常没有办法在系统运行之前就能确定哪个房间
人多哪个房间人少。

lamputa

unread,
Nov 7, 2007, 9:18:40 PM11/7/07
to 高性能网络编程邮件列表
Linker,你这个方法是业务上的补救方法,程序有缺陷用业务的方法去弥补而已。但是请你考虑一下你的方法,首先可以看看现在的游戏中,为什么没有你
提出的方法呢,中国游戏中心没有,QQ GAME没有,但是他们也有同样的问题的,QQ GAME由于其人数几乎是达到满负荷的,所以问题不是很突出,
为什么他们没有类似你提出的概念呢。其次,你说进入空的奖励,但是空不空也是动态的,并不是固定的,如何奖励,一个本来很空的房间,由于有奖励,一下很
多人进入,又一下满了,这也是一个恶循环,而且用户的动态迁移也无谓的增加了通信成本。简单是美,没错,但是这里的简单应该是说用户使用的简单,并不是
说实现的简单,程序要做的就是要做到满足用户使用简单的要求,要做到这个要求程序可能要求很复杂。

> > > 布。- 隐藏被引用文字 -
>
> - 显示引用的文字 -

lamputa

unread,
Nov 7, 2007, 9:30:08 PM11/7/07
to 高性能网络编程邮件列表
Linker,不同意你的看法。
1,简单是美是指用户使用的简单,并不是说实现的简单,也就是你强调的用户体验,你说的方法好似跟用户体验没多大关系,只是程序员简单了,业务上累赘
了,因为运营商没有办法不做这个鼓励政策,如果他想解决这个问题的话。
2,很多游戏平台都有这样的问题,比如中国游戏中心,QQ GAME,为什么没有类似的鼓励出现
3,按照你的说法,去空的房间有奖励,也会有问题。首先房间空不空是动态的,你的奖励也是动态的?还有就是很多用户同时都争着去有奖励的空房间,然后会
导致空房间很快满人,当满了人之后,也会有很多用户离开满人的房间找另外的空房间挤,又导致这个房间变空,这会增加很多无谓的通信,想想,这样的方法跟
不采取方法是不是真的有明显的好处?


On 11月8日, 上午9时14分, Linker M Lin <Linker.M....@gmail.com> wrote:

> > > 布。- 隐藏被引用文字 -
>
> - 显示引用的文字 -

lamputa

unread,
Nov 7, 2007, 9:37:26 PM11/7/07
to 高性能网络编程邮件列表
不好意思,发了一次刷新了发现上面没有,以为没发成功,原来分页了,^_^

> > - 显示引用的文字 -- 隐藏被引用文字 -
>
> - 显示引用的文字 -

lylone

unread,
Nov 7, 2007, 10:06:10 PM11/7/07
to 高性能网络编程邮件列表
如果你只是好奇QQ的棋牌游戏是怎么架构的,可以用ethreal抓包看一下。架构这东西并不是唯一的,不同方案有不同的优势,关键是全局上的均衡。
能解决实际问题,就行了,优劣的说法,无法从讨论中获得定论,还是要去拥有大量资源的公司验证一下,这才是王道

lylone

unread,
Nov 7, 2007, 10:14:24 PM11/7/07
to 高性能网络编程邮件列表
看了zcpro上传的QQ游戏网络架构研究图片,应该是抓包工具在客户端分析的吧。看来QQ的架构确实跟楼主的想法一致,房间跟游戏服务器是一致的,而
且房间是连续的。

顺便问一下zcpro,有没有统计一下,连续的房间数目大致有多少?这个数目大致代表了一台服务器能开多少房间。

lamputa

unread,
Nov 7, 2007, 10:18:45 PM11/7/07
to 高性能网络编程邮件列表
呵呵,好似问题牵涉越来越多。我只有一点一点来描述了

我只是提供一个思路,回收机制你可以不采用,直到最后一个玩家离开房间再把房间给回收也可以,动态生成房间来负载均衡,这种机制在浩方平台上就是这

的。
====================================
首先,如果一个房间只有两三个用户,就是不走,你的房间没办法回收(常发生,有人挂机),其次,动态生产房间满足不了我们的要求,请注意我之前描述的,
用户在登陆之后就会得到一幅服务地图,要求房间数目,对应的IP都是固定的。


至于客户端要有几个连接,这种问题根本不用考虑的。
=========================
我们的连接都是长连接,用户每多一个连接,我们的服务器就多几万乃至几十万个连接,也不可以说不考虑的,服务器是相当繁忙的。

实际上房间服务器的实时性没有你想象的那么高
=====================
棋牌游戏的房间实时性要求是还是比较高的,想想你在QQ GAME中玩拖拉机,看到一个空位置,就想加进去,大家都在抢座位,如果实时性不高,很容易就
是看到有空位其实有人,看到有人的地方其实是空的,相当恼火,因为发了很多时间都不能加入游戏,QQ 在这里也不好,他实时性是比较高的,但是由于玩家
相当多,很难抢到位,时间常常浪费在找位置上面。

如果你把房间服务器和游戏服务器架构在一起,一台服务器也就能开10个房间,这样的架构首先不利于扩展,棋牌类游戏种类很多,你是不是每种类型的都需

附带一个大同小异的房间服务器功能?
=======================================
我确实是这么想的,一个游戏的房间,就有一个该类游戏的服务对象,负责该类服务的事务,扩展的话,你要增加房间,很容易,增加一个这样的对象,让他运行
就可以了(该对象可以运行在同一机器或者新增的机器上).至于你说"附带一个大同小异的房间服务器功能",这个没问题,实现的时候只不过是通过继承来
做,多的只是一个对象。


用户数据上的同步问题
====================
没错,我们的数据库也会是独立的一个黑盒子,里面也会有均衡以及扩展的问题,但是我不是好明白你的意思。无论你把查询的工作放在CS也好,放在WS也
好,对于数据服务器,其工作量是不变的,变化的只是CS,WS本身的负荷,可能你的意思是说把CS,WS都放在同一个模块里实现,该模块又需要数据查
询,其效率会低。但是请你明白,任务就是那么多了,放在一起单台机器可能是没有分开的两台机器效率高,但是请注意我是一台,你是两台,原理是一样的,我
一台带的人数可以少点,反正工作量就是这么多,也没有因为这样而浪费效率,好似问题不大。

分布式服务器的三层架构
========================
三层构架其实是一个概念的东西,连接,逻辑,数据库。其实这个跟这里好似问题不大,即使按照你说的方法,你也是连接跟逻辑都在同一台机器上,不同的是你
把一个逻辑拆分为两个逻辑,我想没必要受这个三层的影响。

> > > 布。- 隐藏被引用文字 -
>
> - 显示引用的文字 -

lylone

unread,
Nov 7, 2007, 10:37:26 PM11/7/07
to 高性能网络编程邮件列表
对于服务器而言,衡量的标准是多少个连接而不是多少个客户。你无法规避客户会建立多少个连接的问题,玩魔兽还有人开两个客户端呢,更别说棋牌游戏了,一
般同时打两桌是很常见的,你需要去考虑一个客户端建立了多少个连接吗?你只要考虑你的服务器能承受多少连接就可以了。
而且,我也说了,这两个连接是分别位于cs和ws上的,而cs和ws并非一台服务器。

如果采用了回收机制,那自然不会在登陆时采用固定地图的方法了,这不冲突,我说的是我这种动态分布的架构,不要跟QQ的机制混淆了。QQ并没有实现房间
拥挤的负荷均衡,而浩方是这样的。

抢座位这回事,大家都是UDP,就像走路跟开车一样,如果没有汽车,大家一起走路,机会是均等的,你觉得这个上面的实时性在哪里呢?

最后说数据库,我说的很明白,第二层的节点越多,就意味着需要直接与数据库沟通的服务器越多,比较我的方案,随着房间的大量拓展,你的数据库瓶颈比我的
架构更快地达到。

我说了,关键还是全局的均衡。

lylone

unread,
Nov 7, 2007, 10:47:14 PM11/7/07
to 高性能网络编程邮件列表
还有一点,可能你没有明白我说的Memory Cache服务器的意义。我的架构中,ws是不会与数据库产生交互的,ws服务器的用户数据是通过他所属
的cs来同步的,所以我说cs是一个Memory Cache服务器,这就意味着一个cs与N个ws构成的集群,只有cs需要与数据库交互,而且cs也
是缓存了提供下面所有ws服务器同步的。

> ...
>
> 阅读更多

zcpro

unread,
Nov 7, 2007, 11:23:13 PM11/7/07
to 高性能网络编程邮件列表
不是用的抓包工具,用的是sysinternals的tcpview,直观,它还可以掐断tcp连接。

我主要分析的是qq的斗地主,因为这一个游戏就几十万在线,比较典型。相同ip的连续房间数在50以上,具体忘了,每个房间350人,同时在线2万左
右;不过我还是有点怀疑这个并发量,因为游戏和其它应用不同,逻辑复杂,很难做并发,所以一般的游戏服务器承载能力都在1万以内;不过也可能是我低估了
qq架构的能力,呵呵,但斗地主逻辑相比麻将要差了一个数量级,有空再研究一下qq的麻将。

lylone

unread,
Nov 7, 2007, 11:54:10 PM11/7/07
to 高性能网络编程邮件列表
如果游戏服务器本身能支撑1万甚至2万的用户,那就真没必要采用我的方法了,也无须考虑什么房间拥挤了,因为一个区就是一台服务器,整个区的所有房间都
在一台服务器上。。。。
还是实践决定架构,这个帖子也该到此结束了。

Lethean

unread,
Nov 7, 2007, 11:57:43 PM11/7/07
to dev4server
dev4server,你好
 
对于房间业务模块与游戏业务模块的物理部署方式这个话题,还是比较感兴趣的,讨论一下。
独立,房间业务以单独的服务器模块实现,优点:方便部署。缺点:效率低、事件同步复杂度高、扩展性差
耦合,以Lib或者COM形式实现,优点:效率高,事件同步简单、扩展方便。缺点:部署复杂度高
举个例子来说:
玩家A坐在位置P1(属于游戏G1),想要换到位置P2(G2),考虑一下这个流程。如果以独立的形式部署,房间服务器(RS)首先要通知G1,玩家A要离开,并等待G1的反馈结
果(RS中保存的G1状态信息是不可信的)。如果得到可以离开的消息,RS再通知G2玩家A想要加入G2的位置P2,并等待回馈,得到确认消息后RS更改自身保存的玩家位置信息。
这个流程中涉及两次网络操作,而且业务本身还有原子性要求(要么A到达P2位置,要么留在原地),效率方面的影响肯定是值得考虑的。更换位置是RS最频繁的业务。
RS中游戏状态信息、玩家状态信息与GS中的游戏状态信息、玩家状态信息同步是更棘手的问题,采用两个不同的Socket分别连接RS和GS,也会引入很多的不确定性。比如,RS收到玩家A想要坐在P1的消息,安排A坐在P1然后给G1发送请求。但如果这时候A的游戏客户端Socket迟迟没有连接到G1怎么办?G1上的其他玩家看到的是,大厅里玩家A就坐在P1,但是游戏中却看不到A。这只是安排位置,还有其他的比如游戏中掉线,掉线后的掉线保护和掉线重连,两个服务器都涉及到这部分业务,而状态又可能不统一,做起来是很麻烦。我们早期的架构是把GS独立出来的,后来的架构又重新设计,采用耦合的方式来做。
扩展性方面,如果各个房间业务很少有变化,无论是独立部署或是耦合部署都可以满足需求。不过我也曾经看到过设计比较花心思的运营商,每个房间内部有很多不同设计,房间内有很多不同种类的交互小游戏,如果有这方面的扩展考虑,房间业务需要很强的定制性,最好也作成Lib,方便个性化设计。
数据库访问肯定要独立出来,我们是把房间的映射管理和数据缓冲层独立出来,把它叫centre server。(CS)
我比较赞同你说的全局均衡,在线总人数未达到峰值的时候,只需要在CS的映射策略上做调整就可以,让每台服务器都以低于较低负载工作。全局处在峰值的时候,也就不存在这个问题了。
 
 
 
2007-11-08

lamputa

unread,
Nov 8, 2007, 12:02:29 AM11/8/07
to 高性能网络编程邮件列表
lylone,明白你的意思。
CS有大量长连接,也需要传输大量数据(座位真的需要比较实时,这个请从你玩游戏过程中的体验出发,你说大家都不实时,就会没所谓,但是请你想一下,你
看到一个座位一直是空的,但是就是一直也坐不下去,请问你感觉如何),所以现在的情况是CS的任务不会很轻,需要均衡,这里没有给出好的方案。
还有需要提出的一点,你上面说只有CS与数据服务器有连接,WS不需要,这个对数据库而言,只是连接数多少的问题,工作量并没有降低,你在那边浪费了2
倍玩家的连接数,在这里赚了WS服务器的连接数,意义不是很大。


比较两个方案,其实可以很容易区分他们的不同,列出他们的优点和缺点就可以了。

1。连接数方面:老方案较优,有效减少连接数,可以节省服务器的网络资源(不要认为无法控制玩家多连接,你说玩家可以看几个游戏什么的,这个不重要,他
开几个游戏在我们游戏平台来看就是几个用户的,只是同一个玩家而已)
2。逻辑清晰方面,新方案较优,把游戏逻辑与房间信息分开。但是我也在想即使他们是在同一台机器上的,逻辑也是分开的,只是他们交互的渠道不同(不同的
机器肯定是用socket,同一台机器可以是socket,也可以是共享内存之类,我想这个可以配置就最好了)
3。负载均衡方面,新方案解决了桌子服务器的均衡问题,但是CS服务器本身的均衡问题没有解决,老方案对均衡问题没有提出解决方法。我今天想了一下,在
老方案中,是否可以这样解决,当他负载重时,象负载轻的服务器发起请求,让负载轻的服务器建立象你那样的WS功能,然后负担重的服务器只需要转发信息就
可以了,不处理游戏逻辑,或者直接让玩家新建连接,跟你现在的模型一样,但是这个模型只限于当负载失衡受影响的玩家

暂时我还是这样想,可能你不这样认为。但是你的想法也是很好的,如果可以比较好的解决CS负载均衡的问题,我想还是很不错的,现在我想焦点在这里。

> > > > > > 刚才下班了。如果对这个架构没问题的话,现在继续说cs服务器的负载均衡控制。- 隐藏被引用文字 -
>
> - 显示引用的文字 -...
>
> 阅读更多

Lethean

unread,
Nov 8, 2007, 12:08:25 AM11/8/07
to dev4server
dev4server,你好
 
我们做斗地主的时候,服务器配置比较差,大概能跑1.5W人(当时主要受限于内存)。而且当时逻辑层的架构还有很大余地可以优化,到2W人是应该可能的。
 
2007-11-08

lylone

unread,
Nov 8, 2007, 12:15:50 AM11/8/07
to 高性能网络编程邮件列表
对于房间业务模块与游戏业务模块的物理部署方式这个话题,还是比较感兴趣的,讨论一下。
独立,房间业务以单独的服务器模块实现,优点:方便部署。缺点:效率低、事件同步复杂度高、扩展性差
耦合,以Lib或者COM形式实现,优点:效率高,事件同步简单、扩展方便。缺点:部署复杂度高
举个例子来说:
玩家A坐在位置P1(属于游戏G1),想要换到位置P2(G2),考虑一下这个流程。如果以独立的形式部署,房间服务器(RS)首先要通知G1,玩家A
要离开,并等待G1的反馈结
果(RS中保存的G1状态信息是不可信的)。如果得到可以离开的消息,RS再通知G2玩家A想要加入G2的位置P2,并等待回馈,得到确认消息后RS更
改自身保存的玩家位置信息。
这个流程中涉及两次网络操作,而且业务本身还有原子性要求(要么A到达P2位置,要么留在原地),效率方面的影响肯定是值得考虑的。更换位置是RS最频
繁的业务。
--------------------------
统一以RS为基准,A向RS请求坐在位置P1,RS告诉A客户端连接G1,A连接上G1后,由G1通知RS客户A的状态,RS才改变A的状态。A离开或
者掉线后,G1通知RS改变A的状态,RS就是一个Memory Cache服务器。这中间没有你说的问题,因为位置的改变是由A请求,实际状态由G1
通知RS改变。
--------------------------

RS中游戏状态信息、玩家状态信息与GS中的游戏状态信息、玩家状态信息同步是更棘手的问题,采用两个不同的Socket分别连接RS和GS,也会引入
很多的不确定性。比如,RS收到玩家A想要坐在P1的消息,安排A坐在P1然后给G1发送请求。但如果这时候A的游戏客户端Socket迟迟没有连接到


G1怎么办?G1上的其他玩家看到的是,大厅里玩家A就坐在P1,但是游戏中却看不到A。这只是安排位置,还有其他的比如游戏中掉线,掉线后的掉线保护
和掉线重连,两个服务器都涉及到这部分业务,而状态又可能不统一,做起来是很麻烦。我们早期的架构是把GS独立出来的,后来的架构又重新设计,采用耦合
的方式来做。

--------------------------
同上,RS只接受G1服务器的状态改变请求,就不存在这个问题。A连不上G1,RS中的A实际状态并未改变,表现在客户端就是抢座无反应,而后刷新时,
发现该座位已经被其他人所占有。
--------------------------

扩展性方面,如果各个房间业务很少有变化,无论是独立部署或是耦合部署都可以满足需求。不过我也曾经看到过设计比较花心思的运营商,每个房间内部有很多


不同设计,房间内有很多不同种类的交互小游戏,如果有这方面的扩展考虑,房间业务需要很强的定制性,最好也作成Lib,方便个性化设计。

--------------------------
这个方面确实存在问题。我把RS跟GS分离的最初出发点,就是因为RS可以维持很大的并发并且用作cache服务器,而GS服务器出于游戏逻辑考虑,很
难支持与RS等同的并发连接。
--------------------------

数据库访问肯定要独立出来,我们是把房间的映射管理和数据缓冲层独立出来,把它叫centre server。(CS)
我比较赞同你说的全局均衡,在线总人数未达到峰值的时候,只需要在CS的映射策略上做调整就可以,让每台服务器都以低于较低负载工作。全局处在峰值的时
候,也就不存在这个问题了。

--------------------------
这块可以详细说说么,关于Center server的具体作用,没看明白
--------------------------

lylone

unread,
Nov 8, 2007, 12:25:53 AM11/8/07
to 高性能网络编程邮件列表
不是连接数量的问题,而是实际查询次数的问题。
试想一下,如果一个玩家进了两个不同房间,开了两桌游戏,而刚好分别位于你所说的两台不同ws上,那么是不是至少需要两次数据库查询?
而如果按照我的架构,这两台ws有可能就属于同一个cs服务器,那么这两次查询实际上就合并为一次,由cs查询缓存而ws是通过cs来获得的。

当然,现在实际情况是游戏服务器同样可以支撑很多并发,那么房间跟游戏就没必要合并在一起了,这点还是用你原先的架构好。

lamputa 写道:

qiaojie

unread,
Nov 8, 2007, 12:35:31 AM11/8/07
to dev4s...@googlegroups.com
瓶颈在哪里都没搞清楚,就开始凭空设计,真够无聊的

假设有1w同时在线均匀分布在50个房间内,75%的人在打牌,20%的人在找座位,5%的人登陆/登出,则:
出牌逻辑计算 750次/秒  通讯量 750 * (1+4)次/秒  (按人均10s出一张牌估算)
房间内用户找座位/状态改变/聊天  200次/秒  通讯量 200 * 400次/秒  (按人均10s改变一次状态)
用户登陆/登出 50次/秒  通讯量 50 * 400次/秒  (假设每秒内有50人次的登陆/登出)

粗略的估算可得知,房间内用户找座位的广播操作是最频繁的,比一桌内打牌用户的操作次数要高1个数量级,而出牌逻辑的计算负载基本可以忽略不计,瓶颈主要在网络通讯上。




在07-11-8,lamputa < lvxu...@gmail.com> 写道:

lamputa

unread,
Nov 8, 2007, 12:58:35 AM11/8/07
to 高性能网络编程邮件列表
qiaoqie,你说的没错,这个也是我所认为的,房间数据的传输量是很大的,请问你有好的解决方法吗,如何解决房间人数的失衡问题。我们的设计也并不
是凭空想象的。对于房间的数据,我还考虑使用P2P的辅助方式来实现,但是跟服务器的连接依然保持。


On 11月8日, 下午1时35分, qiaojie <qiao...@gmail.com> wrote:
> 瓶颈在哪里都没搞清楚,就开始凭空设计,真够无聊的...
>
> 阅读更多

>
> 假设有1w同时在线均匀分布在50个房间内,75%的人在打牌,20%的人在找座位,5%的人登陆/登出,则:
> 出牌逻辑计算 750次/秒 通讯量 750 * (1+4)次/秒 (按人均10s出一张牌估算)
> 房间内用户找座位/状态改变/聊天 200次/秒 通讯量 200 * 400次/秒 (按人均10s改变一次状态)
> 用户登陆/登出 50次/秒 通讯量 50 * 400次/秒 (假设每秒内有50人次的登陆/登出)
>
> 粗略的估算可得知,房间内用户找座位的广播操作是最频繁的,比一桌内打牌用户的操作次数要高1个数量级,而出牌逻辑的计算负载基本可以忽略不计,瓶颈主要在网络 通讯上。
>

> 在07-11-8,lamputa <lvxun...@gmail.com> 写道:

> > > > > > 络上没有那么高的实时性,所以我更愿意叫它Memory- 隐藏被引用文字 -
>
> - 显示引用的文字 -

Lethean

unread,
Nov 8, 2007, 1:20:55 AM11/8/07
to dev4server
dev4server,你好
 
玩家A坐在位置P1(属于游戏G1),想要换到位置P2(G2),考虑一下这个流程。如果以独立的形式部署,房间服务器(RS)首先要通知G1,玩家A
要离开,并等待G1的反馈结
果(RS中保存的G1状态信息是不可信的)。如果得到可以离开的消息,RS再通知G2玩家A想要加入G2的位置P2,并等待回馈,得到确认消息后RS更
改自身保存的玩家位置信息。
这个流程中涉及两次网络操作,而且业务本身还有原子性要求(要么A到达P2位置,要么留在原地),效率方面的影响肯定是值得考虑的。更换位置是RS最频
繁的业务。
--------------------------
统一以RS为基准,A向RS请求坐在位置P1,RS告诉A客户端连接G1,A连接上G1后,由G1通知RS客户A的状态,RS才改变A的状态。A离开或
者掉线后,G1通知RS改变A的状态,RS就是一个Memory Cache服务器。这中间没有你说的问题,因为位置的改变是由A请求,实际状态由G1
通知RS改变。
--------------------------
RS中游戏状态信息、玩家状态信息与GS中的游戏状态信息、玩家状态信息同步是更棘手的问题,采用两个不同的Socket分别连接RS和GS,也会引入
很多的不确定性。比如,RS收到玩家A想要坐在P1的消息,安排A坐在P1然后给G1发送请求。但如果这时候A的游戏客户端Socket迟迟没有连接到
G1怎么办?G1上的其他玩家看到的是,大厅里玩家A就坐在P1,但是游戏中却看不到A。这只是安排位置,还有其他的比如游戏中掉线,掉线后的掉线保护
和掉线重连,两个服务器都涉及到这部分业务,而状态又可能不统一,做起来是很麻烦。我们早期的架构是把GS独立出来的,后来的架构又重新设计,采用耦合
的方式来做。
--------------------------
同上,RS只接受G1服务器的状态改变请求,就不存在这个问题。A连不上G1,RS中
的A实际状态并未改变,表现在客户端就是抢座无反应,而后刷新时,
发现该座位已经被其他人所占有。
 
客户端的表现方面可能会有问题,A玩家选中一个位置,启动客户端,连接到游戏服务器,GS再通知RS,RS这个时候才更新状态。这个过程的时间是以秒为单位计算的,其他玩家看到一个空座位,一直做不上去?如果A一直连不上GS呢,还需要考虑超时机制。这里不只是维护A在RS上的状态,还要考虑每一个游戏的状态,每个位置的状态。
另外,更换位置时的游戏状态肯定不能以RS为准的,还是用上面的例子,很可能玩家A在G1已经开始游戏了,但这个时候RS还没有收到GS发过来的游戏状态同步消息,RS如果按照自己保存的状态,A是可以换位置的,实际状况是A已经在游戏中了,肯定是不能换的。
 
扩展性方面,如果各个房间业务很少有变化,无论是独立部署或是耦合部署都可以满足需求。不过我也曾经看到过设计比较花心思的运营商,每个房间内部有很多
不同设计,房间内有很多不同种类的交互小游戏,如果有这方面的扩展考虑,房间业务需要很强的定制性,最好也作成Lib,方便个性化设计。
--------------------------
这个方面确实存在问题。我把RS跟GS分离的最初出发点,就是因为RS可以维持很大的并发并且用作cache服务器,而GS服务器出于游戏逻辑考虑,很
难支持与RS等同的并发连接。
 
RS支持高并发也并不会带来什么优势啊,RS内部也仍然是以房间单位在管理业务和广播。
 
数据库访问肯定要独立出来,我们是把房间的映射管理和数据缓冲层独立出来,把它叫centre server。(CS)
我比较赞同你说的全局均衡,在线总人数未达到峰值的时候,只需要在CS的映射策略上做调整就可以,让每台服务器都以低于较低负载工作。全局处在峰值的时
候,也就不存在这个问题了。
--------------------------
这块可以详细说说么,关于Center server的具体作用,没看明白
--------------------------
Centre Server(CS)主要是用来管理房间映射关系,GS启动之后会主动到CS注册,CS根据配置策略映射若干个房间到改GS。大厅服务器(其实只是负责发布游戏房间映射信息,可以和Login Server集成)定期从CS获取新的映射表,客户端在登录时得到映射表,之后每隔一段时间刷新一次。其他还有Session Key的保存,全局状态维护等等,都由
CS负责。
 
 
2007-11-08
----- Original Message -----
From: lylone

lylone

unread,
Nov 8, 2007, 1:54:26 AM11/8/07
to 高性能网络编程邮件列表
谢谢Lethean的解答!我明白CS的用途了,CS应该也有控制GS服务器增开房间的功能,GS最初的房间数目也是有限度地开。这样说来,CS也该兼
具cache的功能,而GS是与数据库隔离的,真正的数据库操作应该是由CS来进行的。
这个架构是切合实际的。我之前的架构,cs服务器如果剥离了房间功能,就相当于你们设计中的CS服务器,而ws服务器增加了房间功能,就相当于设计中的
GS服务器。

> Lethean,sunxyl...@gmail.com

lamputa

unread,
Nov 8, 2007, 1:58:48 AM11/8/07
to 高性能网络编程邮件列表
感谢各位的参与,特别是lylone,lethean,zcpro等,我想这个帖子也讨论得差不多了,^_^,希望这次讨论可以给大家带来一定的收
获。

> > 客户端的表现方面可能会有问题,A玩家选中一个位置,启动客户端,连接到游戏服务器,GS再通知RS,RS这个时候才更新状态。这个过程的时间是以秒为单位计算 的,其他玩家看到一个空座位,一直做不上去?如果A一直连不上GS呢,还需要考虑超时机制。这里不只是维护A在RS上的状态,还要考虑每一个游戏的状态,每个位 置的状态。
> > 另外,更换位置时的游戏状态肯定不能以RS为准的,还是用上面的例子,很可能玩家A在G1已经开始游戏了,但这个时候RS还没有收到GS发过来的游戏状态同步消 息,RS如果按照自己保存的状态,A是可以换位置的,实际状况是A已经在游戏中了,肯定是不能换的。


>
> > 扩展性方面,如果各个房间业务很少有变化,无论是独立部署或是耦合部署都可以满足需求。不过我也曾经看到过设计比较花心思的运营商,每个房间内部有很多
> > 不同设计,房间内有很多不同种类的交互小游戏,如果有这方面的扩展考虑,房间业务需要很强的定制性,最好也作成Lib,方便个性化设计。
> > --------------------------
> > 这个方面确实存在问题。我把RS跟GS分离的最初出发点,就是因为RS可以维持很大的并发并且用作cache服务器,而GS服务器出于游戏逻辑考虑,很
> > 难支持与RS等同的并发连接。
>
> > RS支持高并发也并不会带来什么优势啊,RS内部也仍然是以房间单位在管理业务和广播。
>
> > 数据库访问肯定要独立出来,我们是把房间的映射管理和数据缓冲层独立出来,把它叫centre server。(CS)
> > 我比较赞同你说的全局均衡,在线总人数未达到峰值的时候,只需要在CS的映射策略上做调整就可以,让每台服务器都以低于较低负载工作。全局处在峰值的时
> > 候,也就不存在这个问题了。
> > --------------------------
> > 这块可以详细说说么,关于Center server的具体作用,没看明白
> > --------------------------

> > Centre Server(CS)主要是用来管理房间映射关系,GS启动之后会主动到CS注册,CS根据配置策略映射若干个房间到改GS。大厅服务器(其实只是负责发布游戏 房间映射信息,可以和Login Server集成)定期从CS获取新的映射表,客户端在登录时得到映射表,之后每隔一段时间刷新一次。其他还有Session Key的保存,全局状态维护等等,都由

> > --------------------------- 隐藏被引用文字 -
>
> - 显示引用的文字 -

lylone

unread,
Nov 8, 2007, 2:06:55 AM11/8/07
to 高性能网络编程邮件列表
关于房间服务器和游戏服务器的独立部署上,我之所以认为我原先的方案行不通,是考虑到游戏服务器本身并没有多少的压力,不值得分出去,这是因为棋牌游戏
的特殊性。如果是同样拥有房间概念的竞技类网游,这个架构还是可行的。

关于你说的同步问题,我是这样处理的。A向RS请求坐在位置P1,RS通知A连接G1,这时候A并没有坐到P1时,如果B紧接着请求坐到P1位置
上,RS同样通知B去连接G1。这时候就让A和B去跟G1竞争P1的位置,谁先坐上了就是谁,A或者B无论哪个连接不上,就让客户端提示无法坐下,这个
方案并无不妥之处。

至于G1与RS因为都位于一个内网,他们的数据交互基本上不用考虑延迟,还是相当可靠的。同步的问题没有你想象的那么复杂,我见过这样的实际架构。

On 11月8日, 下午2时20分, "Lethean"<sunxyl...@gmail.com> wrote:

> Lethean,sunxyl...@gmail.com

qiaojie

unread,
Nov 8, 2007, 2:10:11 AM11/8/07
to dev4s...@googlegroups.com
现有的棋牌游戏架构已经可以很好的工作,联众、QQ等平台处理上百万同时在线也不存在任何问题。负载不均衡有什么关系,多架几台服务器就是了,以每台最保守运行1w人计算,100w同时在线的也就100来台服务器,这点硬件成本几乎可以忽略不计。而你们讨论的动态负载均衡分布式带来的overhead完全可能超过带来的好处,最终反而得不偿失。



在07-11-8, lamputa <lvxu...@gmail.com> 写道:

Lethean

unread,
Nov 8, 2007, 2:36:22 AM11/8/07
to dev4server
dev4server,你好
 
可以认为同步问题出现的概率低,但肯定不能无视啊。人数多了,时间久了一定会出现的,而且如果之前没考虑到,肯定死得很惨。我举的那个例子,是我们曾经碰到的
实例。换座位的问题只是冰山一角。。后面的掉线保护和掉线重连更要命,所以当时重新整理了一下架构。我们早期的架构和你描述的比较类似,后来进行修改,
最终的架构就是刚才描述的架构。
说句题外话,同步问题是之前设计系统时候最头痛的问题。包括模块间和线程间同步。虽然现在的服务器很稳定,我还是很想把之前的多线程结构改写一下,改成单线程-。-
 

Lethean

unread,
Nov 8, 2007, 2:41:20 AM11/8/07
to dev4server
dev4server,你好
 
恩,实际运营的时候肯定是怎么考虑问题的。我们平台满负载跑1.5W,基本也都是按照1W人上限跑。
刚才说的通过Centre Server动态调整房间数量,我们也在运营中用过,不过后来还是关掉这个功能。实际意义不大。
 
2007-11-08

stamilo

unread,
Nov 8, 2007, 3:30:44 AM11/8/07
to dev4s...@googlegroups.com
看了这么多,好像没有人谈到基础架构,就是分布式,现在小公司可能只有一个机房,但大公司肯定不会只有一个,这样可以分区计算,相应的网络延时也会少几个数量级。

现在大家谈论的,基本上基于,设定一个服务器的最大运算能力,然后可以简单的通过添加计算机增加运算能力。
这个很简单实用,但我们确实可以换一种思考方式,假设我们有一台巨大的计算机,不需要考虑内存、速度,我们该怎样做。

lamputa

unread,
Nov 8, 2007, 4:26:52 AM11/8/07
to 高性能网络编程邮件列表
lylone,说实话,我没能理解按照你的CS/WS的构架后,如何解决房间定位问题。
举个例子,CS1负责游戏G1的房间1~5的,用户登陆后得到一份服务目录,自然记录了G1有1~5个房间,对应IP为CS1的IP。在你的方案中,说
CS1中的房间是动态创建的,那么你怎么让前面登陆的玩家和后面登陆的玩家看到的房间数目以及房间号码等数据是一致的,如果你中间创建出个房间7来,那
么登陆的玩家看不到这个房间,后面登陆的玩家却看到这个房间。

> > 客户端的表现方面可能会有问题,A玩家选中一个位置,启动客户端,连接到游戏服务器,GS再通知RS,RS这个时候才更新状态。这个过程的时间是以秒为单位计算 的,其他玩家看到一个空座位,一直做不上去?如果A一直连不上GS呢,还需要考虑超时机制。这里不只是维护A在RS上的状态,还要考虑每一个游戏的状态,每个位 置的状态。

> > 另外,更换位置时的游戏状态肯定不能以RS为准的,还是用上面的例子,很可能玩家A在G1已经开始游戏了,但这个时候RS还没有收到GS发过来的游戏状态同步消 息,RS如果按照自己保存的状态,A是可以换位置的,实际状况是A已经在游戏中了,肯定是不能换的。


>
> > 扩展性方面,如果各个房间业务很少有变化,无论是独立部署或是耦合部署都可以满足需求。不过我也曾经看到过设计比较花心思的运营商,每个房间内部有很多
> > 不同设计,房间内有很多不同种类的交互小游戏,如果有这方面的扩展考虑,房间业务需要很强的定制性,最好也作成Lib,方便个性化设计。
> > --------------------------
> > 这个方面确实存在问题。我把RS跟GS分离的最初出发点,就是因为RS可以维持很大的并发并且用作cache服务器,而GS服务器出于游戏逻辑考虑,很
> > 难支持与RS等同的并发连接。
>
> > RS支持高并发也并不会带来什么优势啊,RS内部也仍然是以房间单位在管理业务和广播。
>
> > 数据库访问肯定要独立出来,我们是把房间的映射管理和数据缓冲层独立出来,把它叫centre server。(CS)
> > 我比较赞同你说的全局均衡,在线总人数未达到峰值的时候,只需要在CS的映射策略上做调整就可以,让每台服务器都以低于较低负载工作。全局处在峰值的时
> > 候,也就不存在这个问题了。
> > --------------------------
> > 这块可以详细说说么,关于Center server的具体作用,没看明白
> > --------------------------

> > Centre Server(CS)主要是用来管理房间映射关系,GS启动之后会主动到CS注册,CS根据配置策略映射若干个房间到改GS。大厅服务器(其实只是负责发布游戏 房间映射信息,可以和Login Server集成)定期从CS获取新的映射表,客户端在登录时得到映射表,之后每隔一段时间刷新一次。其他还有Session Key的保存,全局状态维护等等,都由

> > --------------------------- 隐藏被引用文字 -
>
> - 显示引用的文字 -

Lethean

unread,
Nov 8, 2007, 8:20:08 PM11/8/07
to dev4server
dev4server,你好
 
呃,不是很明白。。
 
2007-11-09

Lethean

unread,
Nov 8, 2007, 8:21:33 PM11/8/07
to dev4server
dev4server,你好
 
用户每隔一段时间请求一次房间列表。
 
2007-11-09

zcpro

unread,
Nov 8, 2007, 8:37:49 PM11/8/07
to 高性能网络编程邮件列表
哇,对你们公司的游戏架构很感兴趣,是房间服务器和游戏逻辑服务器分开的吗?这1.5w人是指一个房间服务器下所有游戏服务器的人数还是单个游戏服务器
人数?是实际运营的人数还是通过测试程序推论的?1.5w人在线时单个请求的延迟大概有多少(从发请求到得到应答的一个来回)?我们公司的某麻将目前只
能跑1k左右,服务器性能也是比较差的,牌类估计×3差不多了,房间和游戏逻辑没有拆开,在一个exe里。


On 11月8日, 下午1时08分, "Lethean"<sunxyl...@gmail.com> wrote:
> dev4server,你好
>
> 我们做斗地主的时候,服务器配置比较差,大概能跑1.5W人(当时主要受限于内存)。而且当时逻辑层的架构还有很大余地可以优化,到2W人是应该可能的。
>

> Lethean,sunxyl...@gmail.com
> 2007-11-08----- Original Message -----

sunway

unread,
Nov 8, 2007, 8:52:26 PM11/8/07
to 高性能网络编程邮件列表
麻将算法如果不优化跑个1~2K很正常,因为逻辑比较复杂么,因为麻将里面可能有递归类的运算,
如果优化算法可以带更多的用户。

Lethean

unread,
Nov 8, 2007, 9:04:14 PM11/8/07
to dev4server
dev4server,你好
 
房间服务器和逻辑服务器是整合在一起的,用Lib的形式。所说的人数都是指单个游戏服务器支持人数,1.5W是测试程序跑出来的数据(满负荷状态),实际运营我们把上限
定在1W。单个请求延时很低,基本可以忽略。麻将我们没有做,不过麻将的逻辑会复杂很多,可比性不是很强。
 
2007-11-09

http://groups.google.com/group/dev4server

unread,
Nov 8, 2007, 10:45:21 PM11/8/07
to 高性能网络编程邮件列表
握手,我们公司的麻将,也是房间+逻辑在一个exe,单服务器带2000+(实际运营状态),看着这几W几W的,真自惭。。。。


On 11月9日, 上午9时37分, zcpro <zcul...@gmail.com> wrote:

arcnode

unread,
Nov 9, 2007, 12:18:32 AM11/9/07
to 高性能网络编程邮件列表

刚准备说"简单问题复杂化。。。",一看Linker M Lin把我要说的话已经说了。赞一个。。。
很多问题别考虑太多,用户感觉速度慢了一部分人会换房间的,这个比例可以自己去分析。

Tony Huang

unread,
Nov 10, 2007, 11:22:59 PM11/10/07
to 高性能网络编程邮件列表
我最近也在设计一个服务器端的框架,正好乘着这个机会提出来,和大家一起探讨一下:

首先,我把游戏的服务器端划分成几个不同服务:
(1)房间管理服务
(2)桌子管理服务

游戏服务器对外服务的带宽肯定会比服务器之间内部通讯的带宽要小,所以所有的对外操作都通过一层proxy server来
而内部的所有服务器都是同质化的worker server,组成一个compute farm。

在内部服务器中设置一台balance server,负责动态地把服务实例分配到worker server上

所有的服务实例都分成2种:
(1)物理服务实例:实际在某个worker server上执行的服务实例
(2)虚拟服务实例:用户见到的服务实例

物理服务实例空闲的定义:
如果没有用户连接到该实例,则认为该实例空闲

以房间服务为例:
首先我们创建5个物理实例,在5台不同的worker server上,然后创建20个虚拟实例(也就是用户在客户端上看到的20个房间)。这是
物理实例和虚拟实例还没有进行绑定。
当有一个用户试图进入某个房间(比如房间5)时,就认为用户试图连接虚拟实例5,这时balance server就将虚拟实例5和当前最空闲的
worker server上的空闲物理实例进行绑定(如果,此worker server上没有空闲物理实力,则创建一个),为用户提供服务。

这样的话就充分利用了所有worker server的计算资源,并不将他们局限于某种类型的服务,也实现了无论是房间还是桌子服务的动态均衡

不知道大家觉得,这种方案是否可行

lamputa

unread,
Nov 11, 2007, 12:11:46 AM11/11/07
to 高性能网络编程邮件列表
我觉得还是有问题的,如果感兴趣,请加我QQ一起讨论 25502497

> > - 显示引用的文字 -- 隐藏被引用文字 -
>
> - 显示引用的文字 -

stamilo

unread,
Nov 11, 2007, 7:55:21 PM11/11/07
to dev4s...@googlegroups.com

对 Tony Huang 的思路,我画了个图来表示, :)
图分上下两个部分,T表示桌子,虚线的表示动态的,实线表示静态的。

我觉得这个思路很好,很好的体现了模块化划分的原则, 相比,将login和game全放在一个exe中,要好得多。
其实,我们还可以在login server前加入负载均衡层,还有监控层。。。。,还可以做统一的回放业务,。。。。很简洁,而且和业务无关,人员职责也好划分。
DOC071112.pdf

zcpro

unread,
Nov 11, 2007, 9:47:25 PM11/11/07
to 高性能网络编程邮件列表
愿望是美好的,但就怕仅限于是个美好的愿望。
就一个问题,同一个房间内的玩家是需要交互的,例如玩家a从1号桌切换到2号桌,整个逻辑房间的玩家都需要知道这个消息,如果这个房间的桌子散落在不同
的服务器上,怎么解决这个问题?即使解决了,估计通讯量也很可观,当然在内网这个可能不会成为瓶颈。
另外如果用erlang来实现就当我什么都没说。


On 11月12日, 上午8时55分, stamilo <stam...@gmail.com> wrote:
> 对 Tony Huang 的思路,我画了个图来表示, :)
> 图分上下两个部分,T表示桌子,虚线的表示动态的,实线表示静态的。
>
> 我觉得这个思路很好,很好的体现了模块化划分的原则, 相比,将login和game全放在一个exe中,要好得多。
> 其实,我们还可以在login
> server前加入负载均衡层,还有监控层。。。。,还可以做统一的回放业务,。。。。很简洁,而且和业务无关,人员职责也好划分。
>

> DOC071112.pdf
> 14K下载

lamputa

unread,
Nov 11, 2007, 10:36:51 PM11/11/07
to 高性能网络编程邮件列表
没错,他的设计问题最大就在于效率上
由于充分的分布与动态性,使得玩家在不同的桌子跳动,需要动态的连接等问题。
我们从玩家的角度来看,第一玩家需要完整的快速的房间信息,第二,玩家在不同的房间或者桌子跳跃,服务器最好有快速的反应。基于第一点,要求一个房间的
数据,最好是分布在同一个物理机器上的,基于第二点,由于换座位的频繁,不适宜每次换座位都需要重新连接,其三,由于实时性的要求,最好尽量少转发。

之所以我刚开始的时候提出玩家只要建立连接后就不断开连接,也不建立新的连接,除非他不玩这种游戏。并且同一个房间的数据都是在同一个物理机器上的(同
一个物理机器可对应N个房间)。都是基于上面的考虑。我最初的问题是这种实现有时候无法做到很好的均衡(房间人数的失衡引起的)。所以我现在的想法还是
保留原来的构架,但是对于均衡的问题,我暂时的想法就是,在空闲的服务器上开辟worker服务,把一个桌子的逻辑处理从烦闷的服务器分配到空闲服务器
上,以此做平衡。

> > 14K下载- 隐藏被引用文字 -
>
> - 显示引用的文字 -

stamilo

unread,
Nov 11, 2007, 10:58:26 PM11/11/07
to dev4s...@googlegroups.com
我是这样看的,在动态的情况下,桌子是在游戏进入后建立的,所以,玩家跳转的过程是在login服务器上做的。

看来你还是没有层次划分,不要将所有的鸡蛋放在一个篮子里面(不是很恰当)。

而且,一局游戏结束后,你还可以再来一次平衡。

还有,效率问题,其实,排除其他开销,所以计算总量是一样的,只有因为模块划分,在部署到多台计算机上的时候,会增加内网网络通讯量,但这样的好处是 协议和合作。

再,所有的问题都源于你认为 在1台机器上cpu负载为100%,而有很多机器才10%,觉得心理不舒服,你要的是所以机器cpu负载都是相同的,这个想法不是很好,因为你对机器的规划就是能运行给定的负荷,你就不需要替他们担心到底那台机器幸苦点了;除了所有机器都是满负荷,你的规划早就订好了,

添加机器,很简单的!!!!

我们还是不要把精力放在解放 任劳任怨的机器上, 放在ACE上多好。

Tony Huang

unread,
Nov 12, 2007, 8:48:39 AM11/12/07
to 高性能网络编程邮件列表
我总结了一下,主要有以下几个问题:

(1)转发导致效率低下
对于这个问题,昨天晚上和我lamputa在qq上讨论过,其实转发这层不是必须的。
用户可以直接动态地连接到位他提供服务的物理服务器上,对于这个问题我就不再详细论述,贴上昨天晚上的聊天记录,大家就可以明白我的意思了(请
按从下往上的顺序看):
"
Tony.Huang (2007-11-11 22:40:10)
如果房间的人数多起来了,那么服务器的负载就重了,后面创建的房间实例就被分配到其他服务器上了啊!

Forever(jet) (2007-11-11 22:39:20)
绑定之后就不改变,如何适应房间人数动态变化这个情况
Tony.Huang (2007-11-11 22:38:38)
如果房间已经有人,那么该房间实例已经和物理实例绑定,在取得列表的时候就可以告知客户端该服务器的ip了

Forever(jet) (2007-11-11 22:38:32)
恩,有个翻译的
Tony.Huang (2007-11-11 22:38:03)
很简单,当用户试图连接一个没有人的房间的时候(该物理实例还没有被创建),那么客户端会再向主服务器请求这个房间的ip,这是主服务
器就会创建一个物理实 例,并将该物理实例所在服务器的ip回传给用户

Forever(jet) (2007-11-11 22:36:46)
用户要进入房间2,他怎么知道要连哪个IP
Forever(jet) (2007-11-11 22:36:14)
恩,我明白了
Tony.Huang (2007-11-11 22:35:54)
我的意思是,房间在被物理创建的时候,会根据各个服务器的负载状况,选择负载最轻的,于其上创建物理实例

Forever(jet) (2007-11-11 22:35:53)
那好,用户登陆的时候,你怎么告诉用户,他该连接哪台服务器呢
"

但是转发的好处我认为主要有以下几点:
a) 屏蔽了不同网络的差异(比如电信、网通、教育等等)
b) 实现了内部服务器与外部服务器的隔离,充当了一个防火墙的角色
c) 用户与服务器之间的连接可以只需要1个,而服务器将请求转发到内部物理worker服务器时,也只需要与每个与它有业务关系的服
务器保持1个连接

(2)房间服务器与桌子服务器可能不是同一台物理服务器,导致用户频繁建立和终止链接
对于这个问题,我可能是我对架构的表述可能不够清楚。首先,我的worker server上所运行的服务并不一定都是房间服务实例或者桌子服
务实例,它有可能既有房间实例也有桌子实例,这样,balance server可以优先把某个物理房间实例中的桌子服务实例分配到同一台物理服务器
上,这样也可以实现用户与服务器只有1个链接,连接也不需要频繁地中断和建立,同时也可以取消掉转发层。
如果采用以上方案,将会有两个关联的问题,我再一一解释:
a) 如果房间所在的物理服务器负荷已经非常重了,如果再建立桌子实力可能会导致服务质量下降怎么办?
我觉得对于这个问题,其实处理策略也很简单。 我上面说过,是优先分配到该服务器,如果该服务器已经不堪重负了,那么就自动选择除该物
理服务器外有最多该房间桌子物理实例的服务器或者负担最轻的服务器,这样虽然某些用户需要经常建立连接和断开连接,但是这样也能提高总的连接的利用
率。
b) 就算房间服务和桌子服务在同一台物理服务器上,但是由于是两个服务,用户依然需要与该服务器建立2个连接,如何解决。
我的解决方案是这样的,每一台物理服务器对外服务的端口只有一个,通过设计一个service proxy,统一在本服务器内转发服务
请求,就可以实现用户与一个服务器只需要保持1个长连接。
举个例子,假设房间服务和桌子服务都在物理服务器1上,那么当用户进入这个房间的时候,就连接到这个物理服务器的service
proxy上,然后通过通讯协议来告知proxy,该请求应该被转发到那个服务实例去。也就是通过1条物理连接,实现了多条可变的逻辑连接。
(3) 关于没有层次划分的问题
从来架构都是仁者见仁智者见智的一块领域。层次划分的方式有很多种,以前我也比较倾向于采取纵向的划分,比如经典的3层架构,再我以往的所有网
站项目中,我都采用的是这种架构。但是随着规模的扩大,我发现这种单纯的纵向划分不利于运算的并行化,所以就参照j2ee的方式设计了这种横向和纵向相
结合的方式。也就是说,我把任何层次(纵向)中的任何模块(横向)都划分成了服务,通过balance server进行统一的调度,实现方便的扩展
(在很大的一个范围内,可以实现加1台机器就线性地增加1份性能)。
(4) 是否太照顾机器的感受
对于这个问题,我是这样认为的。 我并不在乎机器的感受,但是我在乎用户的感受,一个cpu100%的机器对用户所提供的服务的质量,在很大的
可能性上要比20%的要差。


不知道大家对我的回答是否满意:)

On 11月12日, 上午11时58分, stamilo <stam...@gmail.com> wrote:
> 我是这样看的,在动态的情况下,桌子是在游戏进入后建立的,所以,玩家跳转的过程是在login服务器上做的。
>
> 看来你还是没有层次划分,不要将所有的鸡蛋放在一个篮子里面(不是很恰当)。
>
> 而且,一局游戏结束后,你还可以再来一次平衡。
>
> 还有,效率问题,其实,排除其他开销,所以计算总量是一样的,只有因为模块划分,在部署到多台计算机上的时候,会增加内网网络通讯量,但这样的好处是
> 协议和合作。
>
> 再,所有的问题都源于你认为

> 在1台机器上cpu负载为100%,而有很多机器才10%,觉得心理不舒服,你要的是所以机器cpu负载都是相同的,这个想法不是很好,因为你对机器的规划就是 能运行给定的负荷,你就不需要替他们担心到底那台机器幸苦点了;除了所有机器都是满负荷,你的规划早就订好了,


>
> 添加机器,很简单的!!!!
>
> 我们还是不要把精力放在解放 任劳任怨的机器上, 放在ACE上多好。
>

zcpro

unread,
Nov 12, 2007, 8:55:24 PM11/12/07
to 高性能网络编程邮件列表
关于为什么需要转发服务器再说一句,我是从玩家需求的角度考虑的。玩家a和b是好朋友,但是a和b一个使用电信一个使用网通,如果由系统自动分配服务
器,如何能满足他们两个想在一起玩的需求?不用转发的话。

srdr...@gmail.com

unread,
Nov 28, 2007, 3:13:27 AM11/28/07
to 高性能网络编程邮件列表
呵呵呵,我觉得就不要让玩家挑房间。所有的玩家就像进入一个虚拟化的世界。 有很多玩家在等。三个人能玩一个斗地主,玩家只需点击一个按钮"进入游
戏"即表示愿意接受服务器调度,然后服务器把三个这样的玩家调度到一起,开始玩游戏。就这样。多简单多简明。还进什么大厅房间都是多余的。更进一步优
化,在玩家登录时做一个简单测试,比如是什么网络,哪个地区,把相同地区的玩家调度在一起,重新连接到相同地区的服务器上,会运行更快。

srdr...@gmail.com

unread,
Nov 28, 2007, 3:18:39 AM11/28/07
to 高性能网络编程邮件列表
我继续讲,就像GOOGLE的服务器一样,你一搜索的时候,你知道GOOGLE从哪台服务器上获取搜索结果吗,你根本不知道。那GOOGLE 完全是透
明完成这些。根本不需要你知道。对于用户体验来讲,这才是最友好的方式。什么大厅房间只是一种思维束缚。

tao yuan

unread,
Nov 28, 2007, 3:40:50 AM11/28/07
to dev4s...@googlegroups.com
这个从用户的角度看,是行不通的,很多打牌的人都是有固定的对手和同伴的。
程序设计应该从用户的角度出发,用户才是根本。


在07-11-28,srdr...@gmail.com < srdr...@gmail.com> 写道:

Daniel Lv

unread,
Nov 28, 2007, 3:48:57 AM11/28/07
to dev4s...@googlegroups.com
同意,就好像网游选服务区一样,总不能大家在一个区呀。
--
=====================================
Name : Daniel Lv
Email : lgn...@gmail.com
=====================================

srdr...@gmail.com

unread,
Nov 28, 2007, 4:05:37 AM11/28/07
to 高性能网络编程邮件列表
没问题,固定的对手同伴,我们可以有好友列表啊。这个不是更方便吗?难道大家非得进那个房间碰面,在那个房间玩吗?

提供一个快捷的进入方式是为了方便那些快速进入。您讲的确实也是一种需求。这个要实现也是可以的,可以临时创建一个桌面,有个桌面号,直接提供给朋友进
来就可以。或者邀请我好友列表上的好友进来。作为被邀请的,可以单独提示被邀请,或者朋友给了一个桌面号,直接输入然后回车就进入桌面。也是可以的。可
以改善原有的QQ方式的流程。

不过QQ的方式也是有他的特点,像一个真实的游乐场,可以逛来逛去,可以浏览各个房间,都有些什么人。不过我觉得增设一个快捷的直接加入游戏的按钮,所
有愿意以这种方式加入游戏的用户都按游戏规则,三人一组,四人一组安排到一起这种方式,其实跟原有的也不冲突,在现有基础上加也是可以的。好处就是这样
很方便,很多偶尔想上来玩一下的不用点这么多乱七八糟的玩意了

stephen.nil

unread,
Nov 28, 2007, 9:12:55 AM11/28/07
to 高性能网络编程邮件列表
Hi,all

最近把操作系统从 2.4 内核升级到了 2.6 内核。

2.4 的时候,有一个 bdflush
http://www-900.ibm.com/cn/support/viewdoc/detail?DocId=XPXP-6ZN2KA
在Linux 2.4内核中/proc/sys/vm/bdflush中
Interval:kupdate工作和刷新的最小频率,默认值是5秒。最小值是0秒最大值是600秒。

由于应用程序写磁盘比较多,因此当时观察到程序周期性地每隔 5 秒就会有一个响应时间的高峰期。
当时把这个参数调整为 1 秒之后,整个程序的响应就平稳了。

升级到 2.6 内核之后,程序又开始出现周期性的每个 5 秒就会有一个响应时间的高峰期。
2.6 相应的叫做 pdflush
http://www.westnet.com/~gsmith/content/linux-pdflush.htm
dirty_writeback_centisecs: Leave alone. The timing of pdflush threads set by this parameter is so complicated by rules in the kernel code for things like write congestion that adjusting this tunable is unlikely to cause any real effect. It's generally advisable to keep it at the default so that this internal timing tuning matches the frequency at which pdflush runs.

但是调整了之后,这个参数却没有起到作用。

不知道这里有没有人遇到过类似的问题?能否说一说解决的方法?

Best Regards,

Stephen Liu

stephen.nil

unread,
Nov 28, 2007, 9:12:55 AM11/28/07
to 高性能网络编程邮件列表
Reply all
Reply to author
Forward
0 new messages