好了,我们的共同认识是一台服务器可以承担几个房间的服务,比如服务器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,由于有一个房间是很满人的,所以这个开销也是不小的。
这里要考虑的一个比较重要的问题就是每一个玩家看到的信息都是以房间为单位的,而这个数据又是要求实时处理的。不知道各位有什么好的方法可以处理这个问
题
On 11月6日, 下午5时32分, egg <egg.t...@gmail.com> wrote:
> 迁移是把玩家从房间1移动到房间2还是2个服务器同时服务房间1呢?
> > 题- 隐藏被引用文字 -
>
> - 显示引用的文字 -
我的想法是这样的,1-100号房间其实位于某一台Memory Cache上,而房间中的每台桌子才真正与业务服务器相关联,如此一来,一个房间中的
不同桌子,实际上是位于不同的节点服务器上的。利用这种方法,非常容易地把拥挤房间的用户分散到闲散的节点业务服务器上去进行游戏。而刚好房间这个概
念,本来就是适用于Memory Cache这种性质的服务器。
这种方案,就无需去考虑什么房间迁移了。房间所在的Memory Cache服务器,既可以帮助用户建立联系,也可以进行节点服务器的负载均衡,还可以
进行控制数据的转发工作。
一台Memory Cache服务器(房间)配合N台业务服务器(桌子),组成了一个大的节点,逻辑上就是单独的一层架构。
> > > > - 显示引用的文字 -- 隐藏被引用文字 -
>
> - 显示引用的文字 -
On 11月7日, 下午2时42分, stamilo <stam...@gmail.com> wrote:
> lylone 的方法其实很好,
> 我们将 Memory Cache看作经理, 将业务服务器看作 worker,
> 经理做得只是联系工作, cpu负载轻,网络负载重;
> worker 相反,cpu负载重,网络负载轻, 作主要的业务逻辑(聊天、棋牌逻辑。。。),
> 这样,worker的工作可以独立出来,做并行计算。
>
> 网络游戏,接入服务器和业务服务器的划分相信大家都能接受,接入服务器的负载均衡相信大家也能做到,而业务服务器的负载均衡才是重点,通过并行计算应该是个很好 的解决方法。
>
> 还有,不要局限于房间和桌子,他捆住了你的手脚,让你在规划上就限制了服务器。
>
对于房间服务器而言,他已经拥有这些玩家的状态信息,谁在几号桌,几号桌开始了游戏,哪些玩家被分配到了哪台业务服务器,这些都是业务服务器牵线搭桥
的,他有记录,根本不需要向业务服务器沟通查询!
只有在玩家离开桌子时,业务服务器才需要通知一下房间服务器,改变玩家的状态,如果整张桌子的玩家全部离开,那么该桌号就跟原先的业务服务器脱离关系,
下次再分配时,就重新根据房间服务器的负载计数来重新安排业务服务器。房间服务器跟业务服务器唯一的数据交流,只有在玩家离开桌子的时候才会发生。
根据一个房间400个用户来算,这样一台房间服务器,可以部署10-50个房间。所以,我才把房间服务器叫做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上面。
忽略了这一层因素,再来看用户的接入。为方便描述,我统一把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 写道:
下面谈谈我的想法,你的构架本来是想把WS独立开来,以达到负载均衡的目的,但是WS所承担的工作量比例相对比较小(只是牌的逻辑计算,没有太多网络负
荷以及处理量要求比较大的房间位置信息),所以,导致前面的CS工作量比较重,但是现在来看还没有做负载平衡,后面的WS工作量比较轻,但是做了负载平
衡。
anyway,很感谢你的讨论,希望能继续。
> > > > > > > > > > 问题发生的时候怎么办呢,比如房间1~5用户爆满,而房间5~10房间的人都很空,造成的结果就是服务器1很繁忙,那么房间1~5的服务速度肯定相对比- 隐藏被引用文字 -
>
> - 显示引用的文字 -...
>
> 阅读更多
现在,对这个架构还有什么问题么?如果没有,我们可以继续说下一个问题,就是怎样也让cs得到负载均衡。
> ...
>
> 阅读更多
> > > > > > > > > > 那么怎么解决这个问题呢,首先想到的是将服务器1和服务器2所服务的房间号尽可能打散,比如服务器1服务1,3,5,7,9房间,服务器2负担- 隐藏被引用文字 -
>
> - 显示引用的文字 -...
>
> 阅读更多
> > > > > > > > > 由于国内网络的特殊性,转发是不可避免的,网通和电信用户想在同一个房间玩,同时要保证双方的网速怎么办,所以只能转发。- 隐藏被引用文字 -
>
> - 显示引用的文字 -...
>
> 阅读更多
On 11月7日, 下午5时10分, lylone <Lias....@gmail.com> wrote:
> > > > > > > > > 由于国内网络的特殊性,转发是不可避免的,网通和电信用户想在同一个房间玩,同时要保证双方的网速怎么办,所以只能转发。- 隐藏被引用文字 -
>
> - 显示引用的文字 -...
>
> 阅读更多
如果从技术角度来解决这个问题,我只有一个理论的方案,关键还是分布,主要是增加了一些散列算法用以精确定位,从而提高性能,这个方案就不谈了,因为缺
乏实际应用。
我说一下策略上的解决方案,以我之前提出的架构为基础,由cs服务器的更上一层服务器来动态控制房间数目。按照我的架构,一台cs搭载一定数量的ws服
务器,按照一个房间400用户计算,整个节点维持20-50个房间不成问题。那么如果你有四个该服务器集群,你可以在上层服务器上首先创建4个房间,这
四个房间分布在这四个集群上,而后采用动态生成房间,当房间剩余减少到一定数量时,从四个集群中选择最空闲(房间数目最少的)的那个集群,增开一个新的
房间。相反,如果剩余房间很多,就回收。(这种回收也就是合并,跟同一台cs服务器上的其他房间合并,从编程角度来讲,甚至只是一个内存标志位的改变。
玩家可能觉得是在13号房间,事实上13号房间已经不存在,被1号房间合并了,他正与1号房间的用户进行游戏)
采取这种分布式思想,就轻易地解决了cs负载均衡的问题。就像我说的,房间号是个抽象的概念,它跟桌号一样,也不是固定在哪个服务器机群上,而是动态分
布。
对客户端而言,保持几个连接并不需要特意去规避,这个不重要。
> ...
>
> 阅读更多
再来说客户的连接数问题,对于客户来说,多几个连接问题都不大,但是对于服务器,如果从一个连接变为两个连接,就连接数而言,似乎也增加了一倍,如果我
们的系统是以大型系统来考虑,也是一个相当客观的资源。
或者我们回头来看看我最初提出来的问题,那个方案似乎只是没有解决房间的失衡问题,其他方面似乎问题不大,不知道基于这个基础,有没有更好的想法。
还是那句话,简单就是美~
成本和用户体验优先~
至于客户端要有几个连接,这种问题根本不用考虑的。玩过QQ游戏的都知道,玩家同时进三四个房间那是常有的事情,更何况业务服务器和房间服务器是分开
的,跟两者各保持一个连接不是更正常吗。
实际上房间服务器的实时性没有你想象的那么高,他只是在玩家数据的同步上需要更高的实时性,尽量减少对用户数据库的查询,避免引起数据库的瓶颈。而在网
络上没有那么高的实时性,所以我更愿意叫它Memory cache服务器,如果你用UDP来构建房间服务器,一台服务器开50个房间以上还是很轻松
的。
我没注意过QQ游戏,估计他的一个区也就是100个房间,基本上一个区就是一个集群。
如果你把房间服务器和游戏服务器架构在一起,一台服务器也就能开10个房间,这样的架构首先不利于扩展,棋牌类游戏种类很多,你是不是每种类型的都需要
附带一个大同小异的房间服务器功能?不同类型游戏的房间服务器,都是单独定制的话,在用户数据和通信协议上会有什么问题,服务器的增量部署是否很容易实
现,这些你都有了详细的方案了吗?
你有想的更细致一些么?在用户数据上的同步,第二层节点也就是房间服务器,是需要跟用户数据库交互的(玩家积分之类的数据),第二层的节点数量越多,这
种同步交互就越复杂越频繁,带来的问题更多。你的架构基本上没有考虑用户数据的同步问题,把所有工作都交给了数据库,也把数据库当成了无限制无瓶颈的资
源。
分布式服务器的三层架构,为什么要分层,每层的目的是什么,只有真正弄清楚这些,才能举一反三,架构出自己的服务器。
lamputa 写道:
----- Original Message -----From: lamputaTo: 高性能网络编程邮件列表Sent: 2007-11-06, 15:08:23Subject: 如何提高服务器利用率(棋牌游戏)
我们很常玩游戏的时候都知道,有的房间人满为患,有的房间空无几人,一般来说,玩家都喜欢去人多的房间玩,因为这样更容易让大家进入游戏,也有更多的游
戏机会,所以上述的情况还是时常发生的。
下面以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的能力,那是非常好的,因为这种不均衡的状况是时时存在的,大家留意一下就知道,而且我们通常没有办法在系统运行之前就能确定哪个房间
人多哪个房间人少。
> > > 布。- 隐藏被引用文字 -
>
> - 显示引用的文字 -
On 11月8日, 上午9时14分, Linker M Lin <Linker.M....@gmail.com> wrote:
> > > 布。- 隐藏被引用文字 -
>
> - 显示引用的文字 -
> > - 显示引用的文字 -- 隐藏被引用文字 -
>
> - 显示引用的文字 -
顺便问一下zcpro,有没有统计一下,连续的房间数目大致有多少?这个数目大致代表了一台服务器能开多少房间。
我只是提供一个思路,回收机制你可以不采用,直到最后一个玩家离开房间再把房间给回收也可以,动态生成房间来负载均衡,这种机制在浩方平台上就是这
样
的。
====================================
首先,如果一个房间只有两三个用户,就是不走,你的房间没办法回收(常发生,有人挂机),其次,动态生产房间满足不了我们的要求,请注意我之前描述的,
用户在登陆之后就会得到一幅服务地图,要求房间数目,对应的IP都是固定的。
至于客户端要有几个连接,这种问题根本不用考虑的。
=========================
我们的连接都是长连接,用户每多一个连接,我们的服务器就多几万乃至几十万个连接,也不可以说不考虑的,服务器是相当繁忙的。
实际上房间服务器的实时性没有你想象的那么高
=====================
棋牌游戏的房间实时性要求是还是比较高的,想想你在QQ GAME中玩拖拉机,看到一个空位置,就想加进去,大家都在抢座位,如果实时性不高,很容易就
是看到有空位其实有人,看到有人的地方其实是空的,相当恼火,因为发了很多时间都不能加入游戏,QQ 在这里也不好,他实时性是比较高的,但是由于玩家
相当多,很难抢到位,时间常常浪费在找位置上面。
如果你把房间服务器和游戏服务器架构在一起,一台服务器也就能开10个房间,这样的架构首先不利于扩展,棋牌类游戏种类很多,你是不是每种类型的都需
要
附带一个大同小异的房间服务器功能?
=======================================
我确实是这么想的,一个游戏的房间,就有一个该类游戏的服务对象,负责该类服务的事务,扩展的话,你要增加房间,很容易,增加一个这样的对象,让他运行
就可以了(该对象可以运行在同一机器或者新增的机器上).至于你说"附带一个大同小异的房间服务器功能",这个没问题,实现的时候只不过是通过继承来
做,多的只是一个对象。
用户数据上的同步问题
====================
没错,我们的数据库也会是独立的一个黑盒子,里面也会有均衡以及扩展的问题,但是我不是好明白你的意思。无论你把查询的工作放在CS也好,放在WS也
好,对于数据服务器,其工作量是不变的,变化的只是CS,WS本身的负荷,可能你的意思是说把CS,WS都放在同一个模块里实现,该模块又需要数据查
询,其效率会低。但是请你明白,任务就是那么多了,放在一起单台机器可能是没有分开的两台机器效率高,但是请注意我是一台,你是两台,原理是一样的,我
一台带的人数可以少点,反正工作量就是这么多,也没有因为这样而浪费效率,好似问题不大。
分布式服务器的三层架构
========================
三层构架其实是一个概念的东西,连接,逻辑,数据库。其实这个跟这里好似问题不大,即使按照你说的方法,你也是连接跟逻辑都在同一台机器上,不同的是你
把一个逻辑拆分为两个逻辑,我想没必要受这个三层的影响。
> > > 布。- 隐藏被引用文字 -
>
> - 显示引用的文字 -
如果采用了回收机制,那自然不会在登陆时采用固定地图的方法了,这不冲突,我说的是我这种动态分布的架构,不要跟QQ的机制混淆了。QQ并没有实现房间
拥挤的负荷均衡,而浩方是这样的。
抢座位这回事,大家都是UDP,就像走路跟开车一样,如果没有汽车,大家一起走路,机会是均等的,你觉得这个上面的实时性在哪里呢?
最后说数据库,我说的很明白,第二层的节点越多,就意味着需要直接与数据库沟通的服务器越多,比较我的方案,随着房间的大量拓展,你的数据库瓶颈比我的
架构更快地达到。
我说了,关键还是全局的均衡。
> ...
>
> 阅读更多
我主要分析的是qq的斗地主,因为这一个游戏就几十万在线,比较典型。相同ip的连续房间数在50以上,具体忘了,每个房间350人,同时在线2万左
右;不过我还是有点怀疑这个并发量,因为游戏和其它应用不同,逻辑复杂,很难做并发,所以一般的游戏服务器承载能力都在1万以内;不过也可能是我低估了
qq架构的能力,呵呵,但斗地主逻辑相比麻将要差了一个数量级,有空再研究一下qq的麻将。
比较两个方案,其实可以很容易区分他们的不同,列出他们的优点和缺点就可以了。
1。连接数方面:老方案较优,有效减少连接数,可以节省服务器的网络资源(不要认为无法控制玩家多连接,你说玩家可以看几个游戏什么的,这个不重要,他
开几个游戏在我们游戏平台来看就是几个用户的,只是同一个玩家而已)
2。逻辑清晰方面,新方案较优,把游戏逻辑与房间信息分开。但是我也在想即使他们是在同一台机器上的,逻辑也是分开的,只是他们交互的渠道不同(不同的
机器肯定是用socket,同一台机器可以是socket,也可以是共享内存之类,我想这个可以配置就最好了)
3。负载均衡方面,新方案解决了桌子服务器的均衡问题,但是CS服务器本身的均衡问题没有解决,老方案对均衡问题没有提出解决方法。我今天想了一下,在
老方案中,是否可以这样解决,当他负载重时,象负载轻的服务器发起请求,让负载轻的服务器建立象你那样的WS功能,然后负担重的服务器只需要转发信息就
可以了,不处理游戏逻辑,或者直接让玩家新建连接,跟你现在的模型一样,但是这个模型只限于当负载失衡受影响的玩家
暂时我还是这样想,可能你不这样认为。但是你的想法也是很好的,如果可以比较好的解决CS负载均衡的问题,我想还是很不错的,现在我想焦点在这里。
> > > > > > 刚才下班了。如果对这个架构没问题的话,现在继续说cs服务器的负载均衡控制。- 隐藏被引用文字 -
>
> - 显示引用的文字 -...
>
> 阅读更多
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的具体作用,没看明白
--------------------------
当然,现在实际情况是游戏服务器同样可以支撑很多并发,那么房间跟游戏就没必要合并在一起了,这点还是用你原先的架构好。
lamputa 写道:
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- 隐藏被引用文字 -
>
> - 显示引用的文字 -
----- Original Message -----From: lyloneTo: 高性能网络编程邮件列表
> Lethean,sunxyl...@gmail.com
> > 客户端的表现方面可能会有问题,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的保存,全局状态维护等等,都由
> > --------------------------- 隐藏被引用文字 -
>
> - 显示引用的文字 -
关于你说的同步问题,我是这样处理的。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
> > 客户端的表现方面可能会有问题,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的保存,全局状态维护等等,都由
> > --------------------------- 隐藏被引用文字 -
>
> - 显示引用的文字 -
On 11月8日, 下午1时08分, "Lethean"<sunxyl...@gmail.com> wrote:
> dev4server,你好
>
> 我们做斗地主的时候,服务器配置比较差,大概能跑1.5W人(当时主要受限于内存)。而且当时逻辑层的架构还有很大余地可以优化,到2W人是应该可能的。
>
> Lethean,sunxyl...@gmail.com
> 2007-11-08----- Original Message -----
On 11月9日, 上午9时37分, zcpro <zcul...@gmail.com> wrote:
首先,我把游戏的服务器端划分成几个不同服务:
(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的计算资源,并不将他们局限于某种类型的服务,也实现了无论是房间还是桌子服务的动态均衡
不知道大家觉得,这种方案是否可行
> > - 显示引用的文字 -- 隐藏被引用文字 -
>
> - 显示引用的文字 -
On 11月12日, 上午8时55分, stamilo <stam...@gmail.com> wrote:
> 对 Tony Huang 的思路,我画了个图来表示, :)
> 图分上下两个部分,T表示桌子,虚线的表示动态的,实线表示静态的。
>
> 我觉得这个思路很好,很好的体现了模块化划分的原则, 相比,将login和game全放在一个exe中,要好得多。
> 其实,我们还可以在login
> server前加入负载均衡层,还有监控层。。。。,还可以做统一的回放业务,。。。。很简洁,而且和业务无关,人员职责也好划分。
>
> DOC071112.pdf
> 14K下载
之所以我刚开始的时候提出玩家只要建立连接后就不断开连接,也不建立新的连接,除非他不玩这种游戏。并且同一个房间的数据都是在同一个物理机器上的(同
一个物理机器可对应N个房间)。都是基于上面的考虑。我最初的问题是这种实现有时候无法做到很好的均衡(房间人数的失衡引起的)。所以我现在的想法还是
保留原来的构架,但是对于均衡的问题,我暂时的想法就是,在空闲的服务器上开辟worker服务,把一个桌子的逻辑处理从烦闷的服务器分配到空闲服务器
上,以此做平衡。
> > 14K下载- 隐藏被引用文字 -
>
> - 显示引用的文字 -
(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上多好。
>