网游服务器中的逻辑与场景管理

elated 2011-11-05 10:24:52
在游戏服务器架构中,逻辑和场景一般是怎么分开处理的?
是架成两个服务器,还在是一个服务器中开两个线程,还是不做区分?
各种方式的优缺点是什么?
...全文
251 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
elated 2011-11-22
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 qq120848369 的回复:]
引用 17 楼 qq120848369 的回复:

引用 16 楼 elated 的回复:

我感觉分开设计不是为了效率,而是为了比较好复用代码


其实服务器设计就那么一回事,没什么难度,你看个lighttpd或者nginx的源码就都清晰了。

一切根据需求而变,不同阶段面临不同的困难,瓶颈随时在变,建议你看一下:豆瓣网技术架构发展史。


不要过早的优化,你去看看石器时……
[/Quote]
有道理
qq120848369 2011-11-19
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 qq120848369 的回复:]

引用 16 楼 elated 的回复:

我感觉分开设计不是为了效率,而是为了比较好复用代码


其实服务器设计就那么一回事,没什么难度,你看个lighttpd或者nginx的源码就都清晰了。

一切根据需求而变,不同阶段面临不同的困难,瓶颈随时在变,建议你看一下:豆瓣网技术架构发展史。
[/Quote]

不要过早的优化,你去看看石器时代的服务端架构就明白了,根本没那么多事事。

当年那么火爆的网游,从来没听说过服务器卡到用户不满,顶多有点问题回档而已。

而且当年的技术水平,和现在相比。。。。
qq120848369 2011-11-19
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 elated 的回复:]

我感觉分开设计不是为了效率,而是为了比较好复用代码
[/Quote]

其实服务器设计就那么一回事,没什么难度,你看个lighttpd或者nginx的源码就都清晰了。

一切根据需求而变,不同阶段面临不同的困难,瓶颈随时在变,建议你看一下:豆瓣网技术架构发展史。
elated 2011-11-19
  • 打赏
  • 举报
回复
我感觉分开设计不是为了效率,而是为了比较好复用代码
luciferisnotsatan 2011-11-10
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 qq120848369 的回复:]

去工作中学经验呗,那么多游戏公司。
[/Quote]
看lz的描述,应该已经是在一家游戏公司里了。

开始可以服务器上开线程,等人多了,可以分成两个。关键是可扩展性。比如,不要用个全局变量来传信息,这样以后拆成两台时,原来代码就没什么用了。一开始就可以考虑socket。
qq120848369 2011-11-10
  • 打赏
  • 举报
回复
去工作中学经验呗,那么多游戏公司。
elated 2011-11-09
  • 打赏
  • 举报
回复
不知道怎么让游戏服务器支持更多人,千人在线依然流畅,更重要的是架构呢还是编码的细节呢?
qq120848369 2011-11-06
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 qq120848369 的回复:]

引用 6 楼 elated 的回复:

引用 3 楼 qq120848369 的回复:
引用 1 楼 qq120848369 的回复:

前端肯定有逻辑服务器做命令解析,解析之后根据业务类型送给不同的服务器做处理响应,响应的内容再回送给你,你再回送给客户.

至于逻辑服务器怎么知道某个业务请求应该送给哪一种服务器以及具体哪一台,可以再做一个dispatch服务器,它在内存里维护各个……
[/Quote]

我这个设计还是有点问题的,比如:A发来1,2,3一共三条消息,请求在点对点聊天服务器被并发处理,最终3条消息可能乱序,所以还是需要设计成libevent的架构。 每个DB线程select若干个前端connection(round-robin分发connection),每个connection有自己的请求队列和应答队列。 这样同一个connection送来的A1,A2,A3可以被按序处理与按序应答了。 不过性能可能稍微差一点,因为每个DB线程处理若干固定connection的DB查询请求,可能运气不好让某些DB线程空闲。
qq120848369 2011-11-06
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 elated 的回复:]

引用 3 楼 qq120848369 的回复:
引用 1 楼 qq120848369 的回复:

前端肯定有逻辑服务器做命令解析,解析之后根据业务类型送给不同的服务器做处理响应,响应的内容再回送给你,你再回送给客户.

至于逻辑服务器怎么知道某个业务请求应该送给哪一种服务器以及具体哪一台,可以再做一个dispatch服务器,它在内存里维护各个服务器集群的状态,根据业务请求将包转给对应的……
[/Quote]

我也不了解,我是之前看过一些blog,有点感悟。

前端若干个网关(也叫逻辑服务器),后端就是若干个场景服务。

前端负责网络I/O,网关数量可以扩展,做负载均衡。

后端是若干类型的场景服务集群,必须说出群这个概念,以及类型这个概念。

每一种类型的服务是一群机器在工作,比如:世界聊天服务器,点对点聊天服务器(自由说话也属于点对点,只要知道屏幕范围内的人物名称即可),战斗服务器。

前端任一网关解析请求,都转给后端对应的服务器,比如点对点聊天服务器。

点对点聊天服务器就可以去查在线用户DB集群(master/slave+memcached),从而获知目标用户在哪个前端网关上,然后就可以将这个消息转给对应的前端网关,让其写给对应的用户。

前端服务器接受用户登录,也去写在线用户DB记录登录情况,这就是是一个扩展性比较好的架构。

楼主说的逻辑和场景有点太微观了,那只是单机上的开发问题,比如:点对点聊天服务器,我该怎么开发?

收到的请求是:A want to chat with B, 所以需要一个I/O线程,接着需要去DB查B在哪一个前端服务器上,
所以需要数据库操作,这个过程注定很慢,怎么办? DB查询单独一个线程拿出去。 那如果大量的请求到来,而前边的查询还没完成,怎么办? 将请求放入队列排队呗。 排队了谁去处理? 因为我们做的是master/slave DB集群+memcached集群,很明显我们可以设置N个DB线程并发去不同的服务器查询不同的请求。

于是我开10个DB线程,那就做一个全局队列用于排队请求,每个前端connectio送来的请求存入队列排队,其他DB线程就不断的去检查队列,有请求就加锁(读写锁)拿走去查询,查询DB可以得到B所在机器的IP,所以查hash找到IP对应B connetion,将这个消息放入该B connection,利用管道触发事件,于是I/O线程就知道取该消息送给B的前端。

以上这叫单机的设计,如何提升性能你需要知道自己想要什么。
笨小鸟 2011-11-06
  • 打赏
  • 举报
回复
都用同一个程序处理的,不会为场景做个单独的服务器的。单独做个服务器逻辑同步起来很麻烦。游戏服务器一般按场景划分服务器,有一个或者多个网关服务器。很多逻辑都是以场景作为单元的比如两个玩家的交互除了聊天之外,交易,进入视野,pk,组队等等都在一个地图内完成的。所以按场景划分服务器比较合理。各种交互同步起来都不用向其他服务器去同步,又能做到分布式。这种方式要把一些公共逻辑放到一个单独服务器比如:聊天,公会逻辑。服务器的逻辑可以多线程也可以不是,最好多线程。服务器台数的多少看人数,人多就把几个主城作为一个服务器,这样的一组服务器可以容纳万人以上。关于DB其实压力不大的,数据库单独一个线程就行了,不要阻塞逻辑线程就行。
elated 2011-11-05
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 qq120848369 的回复:]
引用 1 楼 qq120848369 的回复:

前端肯定有逻辑服务器做命令解析,解析之后根据业务类型送给不同的服务器做处理响应,响应的内容再回送给你,你再回送给客户.

至于逻辑服务器怎么知道某个业务请求应该送给哪一种服务器以及具体哪一台,可以再做一个dispatch服务器,它在内存里维护各个服务器集群的状态,根据业务请求将包转给对应的服务器.

整个业务请求只要带着逻辑服务器IP走……
[/Quote]
感觉这种架构有点复杂了,我们公司的服务器就是一个网关服,再加上一个游戏服.游戏服中的逻辑和场景是在两个线程中,两个线程间发消息,和客户端交互.
youkuxiaobin 2011-11-05
  • 打赏
  • 举报
回复
很好很强大
qq120848369 2011-11-05
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 qq120848369 的回复:]

引用 1 楼 qq120848369 的回复:

前端肯定有逻辑服务器做命令解析,解析之后根据业务类型送给不同的服务器做处理响应,响应的内容再回送给你,你再回送给客户.

至于逻辑服务器怎么知道某个业务请求应该送给哪一种服务器以及具体哪一台,可以再做一个dispatch服务器,它在内存里维护各个服务器集群的状态,根据业务请求将包转给对应的服务器.

整个业务请求只要带着逻辑服务器IP……
[/Quote]

那个配置文件可以人工做分发,也可以集中在一台DB上让逻辑服务器和场景服务器启动时去请求获取。
qq120848369 2011-11-05
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 qq120848369 的回复:]

前端肯定有逻辑服务器做命令解析,解析之后根据业务类型送给不同的服务器做处理响应,响应的内容再回送给你,你再回送给客户.

至于逻辑服务器怎么知道某个业务请求应该送给哪一种服务器以及具体哪一台,可以再做一个dispatch服务器,它在内存里维护各个服务器集群的状态,根据业务请求将包转给对应的服务器.

整个业务请求只要带着逻辑服务器IP走,一切都不是问题.
[/Quote]

我自己设想了一个架构,说来听听。

1,首先启动dispatch服务器集群,并且均启动监听套接字。
2,启动所有逻辑服务器,所有场景服务器,这些服务器提前配置了dispatch集群IP/PORT列表,这些服务器主动连接配置文件中的所有dispatch服务器。
3,经过1,2步,每个dispatch服务器与所有的逻辑服务器+场景服务器保持长连接。每个逻辑服务器与所有的dispatch服务器保持长连接,每个场景服务器与所有dispatch服务器保持长连接。
4,逻辑服务器针对client socket1的请求,哈希散列到某一台dispatch服务器,将请求包+client socket1转发给dispatch服务器。
5,dispatch服务器从 逻辑socket1 上收到请求包,根据请求类型,哈希散列到对应场景服务器集群中的一台 场景socket1,将 client socket1+逻辑socket1+请求包 转发给 场景socket1。
6,场景socket1从dispatch socket1上读到请求包,处理后返回给dispatch socket1应答包.
7,dispatch服务器从场景socket1上读到应答包,根据逻辑socket1,将应答包返回给原先那台逻辑服务器。
8,逻辑服务器读到应答包,根据client socket1,将应答返回给客户端。
pathuang68 2011-11-05
  • 打赏
  • 举报
回复
通常是分开的。

比如有一个很大的地图,一般会有专门的地图服务器来处理人物的所在的位置。
qq120848369 2011-11-05
  • 打赏
  • 举报
回复
前端肯定有逻辑服务器做命令解析,解析之后根据业务类型送给不同的服务器做处理响应,响应的内容再回送给你,你再回送给客户.

至于逻辑服务器怎么知道某个业务请求应该送给哪一种服务器以及具体哪一台,可以再做一个dispatch服务器,它在内存里维护各个服务器集群的状态,根据业务请求将包转给对应的服务器.

整个业务请求只要带着逻辑服务器IP走,一切都不是问题.

64,642

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧