游戏开发论坛

 找回密码
 立即注册
搜索
查看: 154469|回复: 138

游戏服务器技术交流

[复制链接]

7

主题

82

帖子

110

积分

注册会员

Rank: 2

积分
110
QQ
发表于 2007-9-10 09:05:00 | 显示全部楼层 |阅读模式
重回技术怀抱 ---- 开篇


  有段时间没有研究技术了,这次正好看到了新版的mangos,较之以前我看的版本有了比较大的完善,于是再次浏览了下他的代码,也借此机会整理下我在游戏服务器开发方面的一些心得,与大家探讨。

  另外由于为避免与公司引起一些不必要的纠纷,我所描述的全都是通过google能够找到的资料,所以也可以认为我下面的内容都是网上所找资料的整理合集。在平时的开发中我也搜索过相关的中文网页,很少有讲游戏服务器相关技术的,大家的讨论主要还是集中在3D相关技术,所以也希望我将开始的这几篇文章能够起到抛砖引玉的作用,潜水的兄弟们也都上来透透气。

  要描述一项技术或是一个行业,一般都会从其最古老的历史开始说起,我本也想按着这个套路走,无奈本人乃一八零后小辈,没有经历过那些苦涩的却令人羡慕的单机游戏开发,也没有响当当的拿的出手的优秀作品,所以也就只能就我所了解的一些技术做些简单的描述。一来算是敦促自己对知识做个梳理,二来与大家探讨的过程也能够找到我之前学习的不足和理解上的错误,最后呢,有可能的话也跟业内的同行们混个脸熟,哪天要是想换个工作了也好有个人帮忙介绍下。最后的理由有些俗了。

  关于游戏开发,正如云风在其blog上所说,游戏项目始终只是个小工程,另外开发时间还是个很重要的问题,所以软件工程的思想及方法在大部分的游戏公司中并不怎么受欢迎。当然这也只是从我个人一些肤浅的了解所得,可能不够充分。从游戏开发的程序团队的人员构成上也可看出来,基本只能算作是小开发团队。有些工作室性质的开发团队,那就更简单了。

  我所了解的早些的开发团队,其成员间没有什么严格的分工,大家凭兴趣自由选择一些模块来负责,完成了再去负责另一模块,有其他同事的工作需要接手或协助的也会立即转入。所以游戏开发人员基本都是多面手,从网络到数据库,从游戏逻辑到图形图象,每一项都有所了解,并能实际应用。或者说都具有非常强的学习能力,在接手一项新的任务后能在很短的时间内对该领域的技术迅速掌握并消化,而且还能现炒现卖。当然,这也与早期2D游戏的技术要求相对比较简单,游戏逻辑也没有现在这般复杂有关。而更重要的可能是,都是被逼出来的吧!

  好了,闲话少说,下一篇,也就是第一篇了,主题为,服务器结构探讨。

7

主题

82

帖子

110

积分

注册会员

Rank: 2

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

服务器结构探讨 -- 最简单的结构

  所谓服务器结构,也就是如何将服务器各部分合理地安排,以实现最初的功能需求。所以,结构本无所谓正确与错误;当然,优秀的结构更有助于系统的搭建,对系统的可扩展性及可维护性也有更大的帮助。

  好的结构不是一蹴而就的,而且每个设计者心中的那把尺都不相同,所以这个优秀结构的定义也就没有定论。在这里,我们不打算对现有游戏结构做评价,而是试着从头开始搭建一个我们需要的MMOG结构。

  对于一个最简单的游戏服务器来说,它只需要能够接受来自客户端的连接请求,然后处理客户端在游戏世界中的移动及交互,也即游戏逻辑处理即可。如果我们把这两项功能集成到一个服务进程中,则最终的结构很简单:

  client ----- server

  嗯,太简单了点,这样也敢叫服务器结构?好吧,现在我们来往里面稍稍加点东西,让它看起来更像是服务器结构一些。

  一般来说,我们在接入游戏服务器的时候都会要提供一个帐号和密码,验证通过后才能进入。关于为什么要提供用户名和密码才能进入的问题我们这里不打算做过多讨论,云风曾对此也提出过类似的疑问,并给出了只用一个标识串就能进入的设想,有兴趣的可以去看看他们的讨论。但不管是采用何种方式进入,照目前看来我们的服务器起码得提供一个帐号验证的功能。

  我们把观察点先集中在一个大区内。在大多数情况下,一个大区内都会有多组游戏服,也就是多个游戏世界可供选择。简单点来实现,我们完全可以抛弃这个大区的概念,认为一个大区也就是放在同一个机房的多台服务器组,各服务器组间没有什么关系。这样,我们可为每组服务器单独配备一台登录服。最后的结构图应该像这样:

  loginServer  gameServer
     |          /
     |        /
     client

  该结构下的玩家操作流程为,先选择大区,再选择大区下的某台服务器,即某个游戏世界,点击进入后开始帐号验证过程,验证成功则进入了该游戏世界。但是,如果玩家想要切换游戏世界,他只能先退出当前游戏世界,然后进入新的游戏世界重新进行帐号验证。

  早期的游戏大都采用的是这种结构,有些游戏在实现时采用了一些技术手段使得在切换游戏服时不需要再次验证帐号,但整体结构还是未做改变。

  该结构存在一个服务器资源配置的问题。因为登录服处理的逻辑相对来说比较简单,就是将玩家提交的帐号和密码送到数据库进行验证,和生成会话密钥发送给游戏服和客户端,操作完成后连接就会立即断开,而且玩家在以后的游戏过程中不会再与登录服打任何交道。这样处理短连接的过程使得系统在大多数情况下都是比较空闲的,但是在某些时候,由于请求比较密集,比如开新服的时候,登录服的负载又会比较大,甚至会处理不过来。

  另外在实际的游戏运营中,有些游戏世界很火爆,而有些游戏世界却非常冷清,甚至没有多少人玩的情况也是很常见的。所以,我们能否更合理地配置登录服资源,使得整个大区内的登录服可以共享就成了下一步改进的目标。

7

主题

82

帖子

110

积分

注册会员

Rank: 2

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

服务器结构探讨 -- 登录服的负载均衡

  回想一下我们在玩wow时的操作流程:运行wow.exe进入游戏后,首先就会要求我们输入用户名和密码进行验证,验证成功后才会出来游戏世界列表,之后是排队进入游戏世界,开始游戏...

  可以看到跟前面的描述有个很明显的不同,那就是要先验证帐号再选择游戏世界。这种结构也就使得登录服不是固定配备给个游戏世界,而是全区共有的。

  我们可以试着从实际需求的角度来考虑一下这个问题。正如我们之前所描述过的那样,登录服在大多数情况下都是比较空闲的,也许我们的一个拥有20个游戏世界的大区仅仅使用10台或更少的登录服即可满足需求。而当在开新区的时候,或许要配备40台登录服才能应付那如潮水般涌入的玩家登录请求。所以,登录服在设计上应该能满足这种动态增删的需求,我们可以在任何时候为大区增加或减少登录服的部署。

  当然,在这里也不会存在要求添加太多登录服的情况。还是拿开新区的情况来说,即使新增加登录服满足了玩家登录的请求,游戏世界服的承载能力依然有限,玩家一样只能在排队系统中等待,或者是进入到游戏世界中导致大家都卡。

  另外,当我们在增加或移除登录服的时候不应该需要对游戏世界服有所改动,也不会要求重启世界服,当然也不应该要求客户端有什么更新或者修改,一切都是在背后自动完成。

  最后,有关数据持久化的问题也在这里考虑一下。一般来说,使用现有的商业数据库系统比自己手工技术先进要明智得多。我们需要持久化的数据有玩家的帐号及密码,玩家创建的角色相关信息,另外还有一些游戏世界全局共有数据也需要持久化。

  好了,需求已经提出来了,现在来考虑如何将其实现。

  对于负载均衡来说,已有了成熟的解决方案。一般最常用,也最简单部署的应该是基于DNS的负载均衡系统了,其通过在DNS中为一个域名配置多个IP地址来实现。最新的DNS服务已实现了根据服务器系统状态来实现的动态负载均衡,也就是实现了真正意义上的负载均衡,这样也就有效地解决了当某台登录服当机后,DNS服务器不能立即做出反应的问题。当然,如果找不到这样的解决方案,自己从头打造一个也并不难。而且,通过DNS来实现的负载均衡已经包含了所做的修改对登录服及客户端的透明。

  而对于数据库的应用,在这种结构下,登录服及游戏世界服都会需要连接数据库。从数据库服务器的部署上来说,可以将帐号和角色数据都放在一个中心数据库中,也可分为两个不同的库分别来处理,基到从物理上分到两台不同的服务器上去也行。

  但是对于不同的游戏世界来说,其角色及游戏内数据都是互相独立的,所以一般情况下也就为每个游戏世界单独配备一台数据库服务器,以减轻数据库的压力。所以,整体的服务器结构应该是一个大区有一台帐号数据库服务器,所有的登录服都连接到这里。而每个游戏世界都有自己的游戏数据库服务器,只允许本游戏世界内的服务器连接。

  最后,我们的服务器结构就像这样:

              大区服务器        
          /     |       \
            /       |       \
           登录服1  登录服2   世界服1  世界服2
         \        |        |       |   
          \      |         |        |
          帐号数据库        DBS     DBS

  这里既然讨论到了大区及帐号数据库,所以顺带也说一下关于激活大区的概念。wow中一共有八个大区,我们想要进入某个大区游戏之前,必须到官网上激活这个区,这是为什么呢?

  一般来说,在各个大区帐号数据库之上还有一个总的帐号数据库,我们可以称它为中心数据库。比如我们在官网上注册了一个帐号,这时帐号数据是只保存在中心数据库上的。而当我们要到一区去创建角色开始游戏的时候,在一区的帐号数据库中并没有我们的帐号数据,所以,我们必须先到官网上做一次激活操作。这个激活的过程也就是从中心库上把我们的帐号数据拷贝到所要到的大区帐号数据库中。

7

主题

82

帖子

110

积分

注册会员

Rank: 2

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

Re:游戏服务器技术交流

打算写一个系列,也算给自己一个交代,但不知道能坚持多久

内容计划的比较多,已经打了一些草稿,还要慢慢整理,从服务器结构到没个独立服务器内部的模块划分,及大的框架代码实现都有所涉及

另外技术人员的文章大都比较中规中矩,我想尝试一下比较轻松的写法,不知道会不会让人觉得有些做作或是有卖弄之嫌

白天上班,只能晚上回去整理,所以会比较慢

149

主题

4981

帖子

5033

积分

论坛元老

Rank: 8Rank: 8

积分
5033
QQ
发表于 2007-9-10 11:16:00 | 显示全部楼层

Re:游戏服务器技术交流

小弟我也是80后,目前还没有入行,也来抛个砖头~ ^_^

关于服务器的安排。我觉得按照楼主所描述的安排,是把一定的任务安排给指定的服务器,而且这种安排是固定的(运行期间无法更改)。那么是否能把这种安排变为动态的?也就是说有这么一组连在局域网里的服务器,有一台服务器作为玩家登录游戏的入口,这个安排是固定的,但其他服务器的任务是根据负荷动态分配的。假如把各个不同的模块做成进程,无论是帐号验证、行走同步、技能逻辑处理还是别的什么,凡是负荷没有很大关联的模块都做成单独的进程,然后由一台特定的服务器进行各个模块进程和服务器的负载监测,把大负荷的模块进程迁移到小负荷的物理服务器上去。这样也许会有更合适的服务器安排,而且通过增加服务器就可以提高负载能力。

18

主题

631

帖子

660

积分

高级会员

Rank: 4

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

Re:游戏服务器技术交流

ding

7

主题

82

帖子

110

积分

注册会员

Rank: 2

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

Re: 游戏服务器技术交流

不错,才刚开了个头就飘小红旗了  [em5]

那个把所有功能组件全部进程化,而且全部动态配置的想法太前卫了

服务器设计不光要考虑灵活性,更要考虑可靠性,稳定性,设计尽可能得简洁,只有在简单的设计无法满足需求的时候才会考虑复杂的实现

7

主题

82

帖子

110

积分

注册会员

Rank: 2

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

服务器结构探讨 -- 简单的世界服实现

  讨论了这么久我们一直都还没有进入游戏世界服务器内部,现在就让我们来窥探一下里面的结构吧。

  对于现在大多数MMORPG来说,游戏服务器要处理的基本逻辑有移动、聊天、技能、物品、任务和生物等,另外还有地图管理与消息广播来对其他高级功能做支撑。如纵队、好友、公会、战场和副本等,这些都是通过基本逻辑功能组合或扩展而成。

  在所有这些基础逻辑中,与我们要讨论的服务器结构关系最紧密的当属地图管理方式。决定了地图的管理方式也就决定了我们的服务器结构,我们仍然先从最简单的实现方式开始说起。

  回想一下我们曾战斗过无数个夜晚的暗黑破坏神,整个暗黑的世界被分为了若干个独立的小地图,当我们在地图间穿越时,一般都要经过一个叫做传送门的装置。世界中有些地图间虽然在地理上是直接相连的,但我们发现其游戏内部的逻辑却是完全隔离的。可以这样认为,一块地图就是一个独立的数据处理单元。

  既然如此,我们就把每块地图都当作是一台独立的服务器,他提供了在这块地图上游戏时的所有逻辑功能,至于内部结构如何划分我们暂不理会,先把他当作一个黑盒子吧。

  当两个人合作做一件事时,我们可以以对等的关系相互协商着来做,而且一般也都不会有什么问题。当人数增加到三个时,我们对等的合作关系可能会有些复杂,因为我们每个人都同时要与另两个人合作协商。正如俗语所说的那样,三个和尚可能会碰到没水喝的情况。当人数继续增加,情况就变得不那么简单了,我们得需要一个管理者来对我们的工作进行分工、协调。游戏的地图服务器之间也是这么回事。

  一般来说,我们的游戏世界不可能会只有一块或者两块小地图,那顺理成章的,也就需要一个地图管理者。先称它为游戏世界的中心服务器吧,毕竟是管理者嘛,大家都以它为中心。

  中心服务器主要维护一张地图ID到地图服务器地址的映射表。当我们要进入某张地图时,会从中心服上取得该地图的IP和port告诉客户端,客户端主动去连接,这样进入他想要去的游戏地图。在整个游戏过程中,客户端始终只会与一台地图服务器保持连接,当要切换地图的时候,在获取到新地图的地址后,会先与当前地图断开连接,再进入新的地图,这样保证玩家数据在服务器上只有一份。

  我们来看看结构图是怎样的:

             中心服务器
          /      \        \
         /        \        \
      登录服     地图1    地图2   地图n
         \        |         /       /
          \       |        /       /
               客户端

  很简单,不是吗。但是简单并不表示功能上会有什么损失,简单也更不能表示游戏不能赚钱。早期不少游戏也确实采用的就是这种简单结构。

149

主题

4981

帖子

5033

积分

论坛元老

Rank: 8Rank: 8

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

Re:游戏服务器技术交流

我有个问题,客户端在整个游戏过程中,网络连接不是持续的,而是要有很多断开再重连的过程,在这个过程中如何保证安全?显然不能每次都重新输入用户名和密码;如果是客户端自动把这些信息在重连时发出,那么用户名和密码就需要长期留在客户端的内存里,那么会给盗号木马提供便利;如果是客户端把一个短期有效的识别数据发给服务器来做用户验证,从第二次传输开始就有被他人截获的可能,而一旦被截获,那么别人就可能抢在合法用户之前就切换服务器,从而导致用户游戏财富的流失或者用户被拒绝服务。所以我想,是否有一种办法,能够避免重新连接,也就是说需要的时候能够把一个网络连接重定向到另一个服务器,但是这个过程仅仅发生在服务器组的局域网内,这个过程是安全的,而对于客户端来说则是透明的过程。
如果要避免断开重连,还有个办法就是用户始终只和一台特定的服务器保持网络连接,由这台服务器来转发客户端与其他服务器之间的数据流,但是这样的话那台特定的服务器的符合就很大了,除非让其他的逻辑服务器一起来客串入口服务器,只是不知道这样会有什么影响。
该怎么处理这样的问题呢?

7

主题

82

帖子

110

积分

注册会员

Rank: 2

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

Re:游戏服务器技术交流

楼上的很对,容我慢慢来说嘛,呵呵

这个结构是早期的结构,现在都不会采用这种每次都要断开再重连的方式了

不过这种方式一样可以做的很安全,每次连接时生成一个有效时间很短的临时密钥就行了

至于你说怕被别人截获,所有的连接都是可以被截获的,问题只在于那个门槛有多高
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-2-25 19:58

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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