游戏开发论坛

 找回密码
 立即注册
搜索
楼主: qinglan

游戏服务器技术交流

[复制链接]

7

主题

82

帖子

110

积分

注册会员

Rank: 2

积分
110
QQ
 楼主| 发表于 2007-9-18 00:06:00 | 显示全部楼层

服务器公共组件实现 -- mangos的游戏主循环

  当阅读一项工程的源码时,我们大概会选择从main函数开始,而当开始一项新的工程时,第一个写下的函数大多也是main。那我们就先来看看,游戏服务器代码实现中,main函数都做了些什么。

  由于我在读技术文章时最不喜看到的就是大段大段的代码,特别是那些直接Ctrl+C再Ctrl+V后未做任何修改的代码,用句时髦的话说,一点技术含量都没有!所以在我们今后所要讨论的内容中,尽量会避免出现直接的代码,在有些地方确实需要代码来表述时,也将会选择使用伪码。

  先从mangos的登录服代码开始。mangos的登录服是一个单线程的结构,虽然在数据库连接中可以开启一个独立的线程,但这个线程也只是对无返回结果的执行类SQL做缓冲,而对需要有返回结果的查询类SQL还是在主逻辑线程中阻塞调用的。

  登录服中唯一的这一个线程,也就是主循环线程对监听的socket做select操作,为每个连接进来的客户端读取其上的数据并立即进行处理,直到服务器收到SIGABRT或SIGBREAK信号时结束。

  所以,mangos登录服主循环的逻辑,也包括后面游戏服的逻辑,主循环的关键代码其实是在SocketHandler中,也就是那个Select函数中。检查所有的连接,对新到来的连接调用OnAccept方法,有数据到来的连接则调用OnRead方法,然后socket处理器自己定义对接收到的数据如何处理。

  很简单的结构,也比较容易理解。

  只是,在对性能要求比较高的服务器上,select一般不会是最好的选择。如果我们使用windows平台,那IOCP将是首选;如果是linux,epool将是不二选择。我们也不打算讨论基于IOCP或是基于epool的服务器实现,如果仅仅只是要实现服务器功能,很简单的几个API调用即可,而且网上已有很多好的教程;如果是要做一个成熟的网络服务器产品,不是我几篇简单的技术介绍文章所能达到。

  另外,在服务器实现上,网络IO与逻辑处理一般会放在不同的线程中,以免耗时较长的IO过程阻塞住了需要立即反应的游戏逻辑。

  数据库的处理也类似,会使用异步的方式,也是避免耗时的查询过程将游戏服务器主循环阻塞住。想象一下,因某个玩家上线而发起的一次数据库查询操作导致服务器内所有在线玩家都卡住不动将是多么恐怖的一件事!

  另外还有一些如事件、脚本、消息队列、状态机、日志和异常处理等公共组件,我们也会在接下来的时间里进行探讨。

59

主题

1490

帖子

1496

积分

金牌会员

Rank: 6Rank: 6

积分
1496
发表于 2007-9-18 08:38:00 | 显示全部楼层

Re:游戏服务器技术交流

看了下,简单说两句。

这种架构的服务器端就是当年DOS时代的水平,离现代Windows商业系统差太远,市场方面也是相若。

换句话说,你看当年占中国市场70%以上的WPS而今何在?

而当年在Windows系统架构下的Word,现今在中国的市场占有率又是多少?

如果在今天还使用DOS时代的服务器架构,那在它上面跑的软件系统,应该和WPS是一样的历史结局。

但是,如果是紧跟时代的脚步,研究在Windows新架构上跑的Word,那么胜利的欣喜,想必谁也无法拒绝,呵呵

3

主题

68

帖子

68

积分

注册会员

Rank: 2

积分
68
发表于 2007-9-18 09:07:00 | 显示全部楼层

Re:游戏服务器技术交流

兴之(6377)你就不要出来丢人了,楼主表理它

149

主题

4981

帖子

5033

积分

论坛元老

Rank: 8Rank: 8

积分
5033
QQ
发表于 2007-9-18 13:07:00 | 显示全部楼层

Re:游戏服务器技术交流

6377还是要理一下的,我也来说几句:
首先,6377是否能给出不同操作系统的服务器端的网络应用和网游应用的部署情况?只需要3个操纵系统:Windows、Linux、FreeBSD,列出这三个系统在不同年份的部署数量(服务器的台数),以及对应的行业,然后再列出在网游行业里这些不同操纵系统的服务器端所对应的服务器流量以及该游戏的在线人数、销售额分布,然后再列出这些服务器每年连续工作的时间以及正常提供服务的时间。如果Windows真如6377所推崇的那么好,那么列出这些比任何说教都有效;可如果列不出这些,那么恐怕不管怎么说教都没有说服力。
当然这可能涉及到商业秘密,所以还有个办法,就是6377你自己用不同的操纵系统进行测试,测试它们的承载能力、安全性、稳定性、成本,然后把你的测试程序和方法列出来,这样也会很有说服力。
当然,我不要求你给出可靠的数据来源,因为我觉得那样有点强人所难了。
然后,请你证明一下楼主所说的服务器架构问题和你所用来类比的“文字编辑器问题”之间具有可比性,因为我所在看不出你所说的“如果今天谁还说他做古老的Dos下的文字编辑器一定能超过今天Windows下的word应用软件的市场份额,那简直就是痴人说梦!”与楼主的贴子有多少关系,更不觉得这能证明楼主所说的东西很烂很过时。如果你不能证明,那么请你收回,这样会提高你的信誉。
第三,如果你有比楼主更好的东东,那么请你像楼主一样写文章来与大家分享,而且能像楼主一样没有说教气,并且能够认真回答回帖里的问题。如果你这么做,我想大家都会对你报以赞赏的态度的,如果你不肯把自己的知识拿出来与人分享,却还要嘲笑他人的分享行为,那么这就纯粹是道德问题了……当然如果你没有什么知识可以拿来分享,那我就不说什么了。
希望6377不要看帖不回哦~  ^_^!

149

主题

4981

帖子

5033

积分

论坛元老

Rank: 8Rank: 8

积分
5033
QQ
发表于 2007-9-18 13:17:00 | 显示全部楼层

Re:游戏服务器技术交流

支持一下楼主,楼主继续~

59

主题

1490

帖子

1496

积分

金牌会员

Rank: 6Rank: 6

积分
1496
发表于 2007-9-18 14:13:00 | 显示全部楼层

Re:游戏服务器技术交流

不是争论谁技术怎么样,就是当年的Novell现在国家核心部门不也用得好好的嘛。什么技术都有适合它的特定市场。

技术不是什么问题,现在我更关心的市场问题,如果是生产Windows赚得多,可以使公司成为Microsoft,最后就是它了。

现在焦点是,你能否在DOS、Freebsd还很流行的时代,就能看到未来会出现Windows,以及它能占领多大的市场份额。

请不要狭义地来比较技术,我支持你们继续。市场才是最终目标。

我以后将不说话,我只看看,呵呵

149

主题

4981

帖子

5033

积分

论坛元老

Rank: 8Rank: 8

积分
5033
QQ
发表于 2007-9-18 22:33:00 | 显示全部楼层

Re:游戏服务器技术交流

呵呵……原来6377在不同的操纵系统平台之间没有偏向?如果有什么观点,也不用如此语焉不详……
说到市场,在我个人看来,任何预见都缺乏足够的说服力,相信的人是相信的,不相信的人却总不会相信,因为这种预测不得不带有太多的个人主观看法,并不能向数学定理那样严谨的证明。而另一方面,当事实发生之后再来强调以前的预测,也往往带有“事后诸葛亮”的味道,因为没有任何办法证明之前的预测是有充足根据的,也无法证明预测与现实的切合不是偶然。

“请不要狭义地来比较技术,我支持你们继续。市场才是最终目标。”
在我看来恰恰相反。诚然技术不能脱离市场,但是如何从市场的角度来评价技术?首先要做的就是“就事论事”的评价技术,就是只从技术的角度来看待技术,如果做不到这一点,那么就无法理解技术,于是就更不可能了解和预测这技术在市场上的前景。市场的确是目标,但是谁都不可能一步登天,不可能在没有充分理解各种不同技术的情况下做出正确判断。

“技术不是什么问题,现在我更关心的市场问题”
我不知道你是做什么工作的,但是就我个人而言,我觉得现在技术还是很成问题的。理论上,在可以预见的将来,技术总是无法满足需求的,因为需求相对于目前人的手段来说几乎是无限的,所以理论上技术永远都是个问题。就实际而言,首先要想一想,国内游戏开发的技术水平如何?《游戏编程精粹》系列,从1到5,其中有多少华人的文章?有多少来自大陆的文章?有多少国人写的游戏编程书籍销往外国?有多少国产的游戏引擎与外国大作相竞争?国内的技术是在跟随还是领导?目前做得比较成功的国产网游,他们的成功是以策划为优势还是以技术为优势?无论是wow还是你所推崇的eve,哪个是国产的?既然你是业内人士,相信这些问题的答案比我更清楚。
如果你认为技术不是问题,那么你有没有办法实现服务器端完整的物理系统?而且能同时在成本、性能和承载能力方面都达到实用?
不知道6377说“技术不是问题”的时候是怎么想的……是不是想着“洋人的技术源源不断地卖进来,用都用不完”?

7

主题

82

帖子

110

积分

注册会员

Rank: 2

积分
110
QQ
 楼主| 发表于 2007-9-19 08:24:00 | 显示全部楼层

服务器公共组件实现 -- 继续来说主循环

  前面我们只简单了解了下mangos登录服的程序结构,也发现了一些不足之处,现在我们就来看看如何提供一个更好的方案。

  正如我们曾讨论过的,为了游戏主逻辑循环的流畅运行,所有比较耗时的IO操作都会分享到单独的线程中去做,如网络IO,数据库IO和日志IO等。当然,也有把这些分享到单独的进程中去做的。

  另外对于大多数服务器程序来说,在运行时都是作为精灵进程或服务进程的,所以我们并不需要服务器能够处理控制台用户输入,我们所要处理的数据来源都来自网络。

  这样,主逻辑循环所要做的就是不停要取消息包来处理,当然这些消息包不仅有来自客户端的玩家操作数据包,也有来自GM服务器的管理命令,还包括来自数据库查询线程的返回结果消息包。这个循环将一直持续,直到收到一个通知服务器关闭的消息包。

  主逻辑循环的结构还是很简单的,复杂的部分都在如何处理这些消息包的逻辑上。我们可以用一段简单的伪码来描述这个循环过程:

    while (Message* msg = getMessage())
    {
      if (msg为服务器关闭消息)
        break;
      处理msg消息;
    }

  这里就有一个问题需要探讨了,在getMessage()的时候,我们应该去哪里取消息?前面我们考虑过,至少会有三个消息来源,而我们还讨论过,这些消息源的IO操作都是在独立的线程中进行的,我们这里的主线程不应该直接去那几处消息源进行阻塞式的IO操作。

  很简单,让那些独立的IO线程在接收完数据后自己送过来就是了。好比是,我这里提供了一个仓库,有很多的供货商,他们有货要给我的时候只需要交到仓库,然后我再到仓库去取就是了,这个仓库也就是消息队列。消息队列是一个普通的队列实现,当然必须要提供多线程互斥访问的安全性支持,其基本的接口定义大概类似这样:

    IMessageQueue
    {
      void putMessage(Message*);
      Message* getMessage();
    }

  网络IO,数据库IO线程把整理好的消息包都加入到主逻辑循环线程的这个消息队列中便返回。有关消息队列的实现和线程间消息的传递在ACE中有比较完全的代码实现及描述,还有一些使用示例,是个很好的参考。

  这样的话,我们的主循环就很清晰了,从主线程的消息队列中取消息,处理消息,再取下一条消息......

1

主题

11

帖子

15

积分

新手上路

Rank: 1

积分
15
发表于 2007-9-19 12:52:00 | 显示全部楼层

Re:游戏服务器技术交流

会不会讲到服务器端游戏世界建模呢?

7

主题

82

帖子

110

积分

注册会员

Rank: 2

积分
110
QQ
 楼主| 发表于 2007-9-19 20:27:00 | 显示全部楼层

Re:游戏服务器技术交流

越往后写越觉得比较吃力,知识不成系统,散的很

一归纳整理,发现断层还太多,就不敢随便乱说

所以,接下来可能选择性地找一些我比较熟悉的内容说下吧

哪块内容理出点头绪,理出点系统来了再写
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-2-25 20:06

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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