游戏服务器浅析

(一)平台选择

windows还是linux?

1、平台费用:如果是大型公司,用windows server就要向微软交点保护费,还有接踵而来的各种软件收费,受不了,如果是小型公司。。。你懂的,所以很多大型公司都选择了linux开发服务器,但不一定就说linux的好。

2、开发环境搭建:windows有现成的VS开发环境,安装一下,一般不会出错,而且像VS助手这样的插件还有联合编译器都很容易安装成功,但linux上安装起来就比较麻烦了,可能要浪费一点点时间了。

3、功能调试:无可厚非,VS的F9,F5,F10,F11都比linux的gdb调试起来要方便许多吧?如果说用打日志方式来作为调试的主要手段,两者确实是一样的,但我只能说,你太有才了。。。

4、运行效率:当然是linux的要高要快啦,大概快25%吧

这里有篇文章,推荐大家看下http://os.51cto.com/art/201006/205628.htm

我个人比较喜欢windows,是的,我就是在小型公司,哈哈。。。由于windows的通用性,使得windows上开发速度非常快,人才引进也方便,开发成本低,开发效率高,这些优点都吸引着我选择windows平台。如果你是大型公司的,linux吧,TX就是linux的,别无选择。

(二)技术选型

java还是c++?

1、c++运行速度比java要快得多,但是现在的硬件环境,让这个特性越来越不被强调。

2、java强大的异常捕捉是c++无法匹敌的

3、java人才的工资稍微低一点点,呵呵

啊,我想说的是,我选择了c++,为啥捏?我是比较看重c++那点速度的,这样在做超大型的国战帮战跨服战时,是非常有利的。

(三)我的开发环境

windows + VS2008 + mysql + lua + python + php + 论坛 + rtx

请允许我介绍一下几个新成员的功能

mysql:数据库,免费,速度快,只能说赞。我见过的游戏公司都是mysql的。

lua:连魔兽都用lua,哥,您就别纠结了,跟着用就是了。

python:脚本语言,是用来写一些工具的,平时有些策划方面的计算问题,或者统计工具这样的小软件,就用python来写,不用编译,写了就可以用,写错了可以马上改,只要别的机器安装了python,那过去运行就是了,运行不了就打开,修改再运行。

php:这个家伙是用来做网页方面的一些事情的,比如服务器分配,对接别的公司的网页,还有。。。公司点餐,哈哈

论坛:论坛是个比较奇怪的东西,我用它来做一些公司的技术归档,有些技术这时候不懂,百度一下,找到了,过几天百度的那篇文章不见了,SB了就。所以就有了论坛,还可以增进公司员工的知识面,多好啊。灌水帖,还可以看看“福利”什么的,多好啊。

rtx:其实,我想用QQ的,但是消息要怎么通过QQ即时通知给相关人员这个我实在搞不定,就只好用RTX了。

    啊,是不是少了个BUG管理?其实我是用论坛做BUG管理的,一个版本一个版本的发,一个单子一个单子地做下来,每个人都能看到其他人的BUG,也能看到其他人的单子,这样,当一个人在做某个单子遇到问题时,就很容易去找这个单子的相关负责人了。但这个用久了之后就发现问题了,BUG的总结迟迟总结不出来,有多少BUG是由于什么原因导致的啊,有多少BUG是不应该的啊,等等。我的解决方法是,有一个典型BUG模块,在这个模块里,把BUG单分类罗列出来,并且有一个统计(每个BUG单都有原因标识),这样就很清楚了。话说为什么选择论坛呢?嘿嘿,开源呗,想怎么改怎么改,而且页面清晰。

(四)这些要不要用?

1、boost,这个东西是很强大,号称c++发展的动力机。个人觉得,还是算了吧,就你一个人会用有什么用,招个新人进来又得重新教,教了之后,人家将来走了又不用,这不是SB的选择么。

2、我还没想到,以前很多的,突然间想不起来,等想到了再说

(五)服务器搭建

我个人比较喜欢以下这一套:

1、登陆服务器

2、网络服务器

3、逻辑服务器(逻辑服 + AI服)

4、数据库服务器

是的,就四个。

(1)登陆服务器

    每当开新服的时候,有一堆玩家要涌入到游戏里来,如果你的游戏火的话,一次性涌入个五、六万都是有可能的,这就要求我们必须设计一个登陆服,他的作用很简单,建立新用户,并且将用户分流。

     怎么分呢?用户是从页面进来的,用户自己已经选好了,我就是XX服的。其实,用户选择进入一个服务器时,会先连接到登陆服,登陆服根据当前在线人数,和登陆服的一些参数,如当前CPU,内存,网络吞吐量等,综合决定是否允许该玩家在此时进入该服务器,如果某一方面因素接近极端了,就不允许玩家在该服务器注册。所以,我们有时会看到某个游戏进不去,提示就是说服务器忙等等。

    登陆服务器接受玩家登陆后,在数据库里创建该玩家的记录,接着把网络服务器的IP和端口发给客户端,客户端断开当前连接,转而连接到网络服务器。注意,这里是网络服务器,不是逻辑服务器,有些游戏没有网络服务器,但个人认为,这样的设计不大好,因为逻辑服务器是最常出现问题的,总不能一出现问题就关机等明天早上再来看看什么问题吧。而如果有网络服务器,那么,一旦逻辑服有问题,还可以直接拉起,只要你设计得好,直接拉起是没问题的。

    一开始,刚在某个区开服的时候,登陆服务器可能会比较多,过一段时间后,登陆的玩家少了,登陆服就可以考虑撤掉了,也就是节省硬件成本(这个在端游上比较常见,页游还比较少)有些页游甚至没有登陆服的概念,直接用游戏逻辑服务器,玩家多了就直接加开逻辑服,这个就可能导致一开始某个服务器撑不了那么多人而卡机,也可能导致由于评估不足而导致浪费逻辑服务器。

(2)网络服务器

    在windows上开发,socket首选是IOCP(页游是IOCP,手游的话像连连看这种的用select也是可以的),网络服务器的作用是用来接受连接和收发数据,网络服务器必须能够把数据暂存在该服务器本身5~10秒(这个时间内,逻辑服应该是能够起服完毕的)。

    网络服务器将接受到的数据发送给逻辑服,让逻辑服务器处理,逻辑服将处理过程中需要发送的数据发往网络服。这里要注意的是,不能按照玩家来收发数据,应该按服务器接收数据的顺序进行,虽然按照玩家来处理数据会有时间片上的公平性,但这个遍历会让你消耗掉大量的资源,可能还会不断的解锁加锁。还有一点要注意的,一个数据包发往逻辑服务器后要等逻辑服返回后才能继续下一步,不能一直向逻辑服务器发包。纳尼?顶解啊?注意过数据库吗?它也是一条条处理的,他不会让你连续发多个语句给它,说我会帮你存起来慢慢处理。连续发包可能当前面一个包造成服务器崩溃时,下一个包会丢失,下一个包如果很普通那就没事,如果是消耗10000元宝的消息包,哥,你伤得起吗?玩家是兴起的动物,通常不理智的,没那个兴,就不会再花那个钱了。

    一个比较好的设计是,在服务器里有两个队列,一个队列,用于写,一个队列用于读,当读的队列空的时候,把写和读的队列调换,这样,加锁解锁就可以大大降低,我见过有的服务器是用一个队列的,这样每次读写都要加锁解锁,性能消耗很大。网络服务器一般可以开两个线程,一个线程用于接收客户端连接,接收客户端消息,接收逻辑服务器消息,另一个线程用于转发客户端消息到逻辑服务器,转发逻辑服务器消息到客户端。这里必须明白,服务器发往客户端和客户端发往服务器的数据量,不是一个数量级的,一般由服务器发出去的会比客户端发过来的要大10~100倍。这主要取决于服务器的在线人数。

(3)逻辑服务器

    逻辑服务器的搭建就要详细规划一下下了。包括在网络服务器和数据库服务器之间的通信,快速的AOI,ID设计,ID段划分,内存池的使用,对于有AI的游戏,还应该增加一台AI服务器,等等,一个好的框架能大大减小服务器出错的几率。

    有人说,单例模式非常棒,这种设计模式如何如何的好,但我要提醒你,逻辑服务器尽可能少的使用单例模式,如果能够对单例的使用设计出一个比较好的开关,那自然可以使用。首先,单例模式的对象都是静态的或者全局的,这就使得单例的对象的析构跟编译的顺序有关,也就是,你得去了解编译器的编译顺序才知道有没有什么隐含的BUG。其二,如果一个单例被正确析构了,又被调用了一次,又会重新构造对象,这个问题就大了。太难查了,这种BUG。

   另外一个,要不要把在线玩家和不在线玩家分别处理?我以一个过来人的身份轻轻的告诉你,千万不要分开处理,千万不要用两个管理器从数据库和从内存中保存玩家数据来处理,难的不是设计,是会忘记,经常会忘记在另外一个管理器中取玩家,而且还很不便于管理,通常加个新的东西,两边都要加。一种好的做法是一个管理器,保存着所有的玩家,当取玩家时优先遍历在线的,再遍历不在线的就可以了。而且,假如一开始就这么做,还可以省掉做竞技场,做排行榜这样的弯路,因为这两个都是要读不在线的玩家数据,你可能会一开始写一个非常垃圾的管理器来做这个事情。

    对于ID的设计,我提个小建议,2位平台ID + 4位服务器ID + 标识ID,可能这个ID会超过int型,没关系,可以用__int64,java的用long。这样的设计是保证在整个游戏的生命期,每个ID都是唯一的,而不会在合服的时候造成ID重复。想想那些一开始做游戏的哥们是多么痛苦地处理这个ID的,我都心疼了。

    lua的设计。对于lua,我们都应该记住,它是函数式语言,一般情况下,不要对lua做过于复杂的模式设计。我提两点建议,一,命名规范。lua文件名建议用英文名称,在文件的一开始就用这个文件名声明一个local 文件名的table对象,比如文件名叫usertask,那么文件的开头应当有local usertask = {} 的声明。之后,该文件的所有函数,都用这个table来限制外部的使用,这样便于锁定文件的访问。二、当一个函数外部文件也可以访问时,请给这个函数取名叫文件名_函数名,如GLOBALDEF_getConfig(),这样,当看到一个函数时就很容易知道是什么函数,该去哪里找它的原型了。

   来讲讲日志文件吧。日志记录有两种方式,一种是log文件,一种是数据库记录。我比较赞同两者互用。对于像指针检查,前端传值检查,这样的日志应该用log文件直接记录,不用单独开线程,因为这个会很少。对于像物品的流程追踪,玩家会用什么物品,这个物品会怎么使用,从物品的出生到死亡这一个过程,应当用数据库记录起来。这份数据往往是作为统计用的。

   差点忘记讲最重要的一个东西了。就是逻辑服线程问题。一般有两种设计,一种是按逻辑来分线程的,一种按地图来分线程。按逻辑来分线程固然好,所有线程都可以同样的忙碌着,按地图来分线程可能就有的线程没事干了。其实,对于页游来讲,玩家会很聚集,所有逻辑都可以只是一个线程,是的,没骗你,你会发现2000个人在一个线程中完全不痛苦。而过不了多久,这2000玩家就剩不到几个了,你合服的速度还没玩家消减的速度快。对于端游,就按地图划分吧,端游由于具有很强的可玩性,策划的脑子都是乱转的,三天两头加地图加大型玩法,人又特别多,如果按逻辑分线程,很多加锁的数据不大好做,而且,玩家在一个地图中很可能会有很多逻辑被分在不同线程。

(4)数据库服务器

    嘿嘿,这个上面有提过一点点,它的设计跟网络服务器的设计差不多。你应该有一个缓冲区,把写库的数据暂存起来,然后慢慢地写入到数据库中。像记录玩家所在位置,这样的写库,可以半小时写一次,像花元宝的,最好就及时落地。这就要求你的数据记录有优先级的关系。对于一个数据库表,我建议一开始就做好分区的操作,在一开始就要估计某个表会多大,然后按照ID分区,这样不会浪费空间,也就是所谓的range分区。另外一个,MySQL数据库建议使用MyISAM引擎,有些公司,是做小型游戏的,使用的是innodb的引擎,没什么问题,但是到了页游就SB了,现在页游要转手游了,同样也可能有个SB的过程。MyISAM是对整表加锁的,innodb是对记录加锁的,so,MyISAM的数据比innodb速度要快多了。

(5)服务器的安全

    互联网说危险不危险,说安全也不安全。说危险吧,时不时就传来了黑客攻击了,服务器崩溃了,说安全吧,你看MSN的内容甚至没有加密。好吧,对于游戏这种赚钱的服务器来说,安全是必不可少的,随便攻击一下都是很伤的。

(1)消息加密解密

     在网络服务器与客户端之间的消息通信,应当是加密的,以防止消息被窃取,用户资料被盗。加密方式有多种,目前流行的就是密码用MD5,其他的消息用一个普通的,速度快的DES。

(2)SQL防注入

    这个要自己要多学学自己使用的数据库了,看看哪些语句,哪些符号是非常特殊的,直接屏蔽掉,不要留下祸患。比如MySQL,要屏蔽的符号就有单引号(' '),双引号(" "),反斜杠(\),注释符(-),结束符(;),还有C++的伤心符(百分号%)等等,我就曾经被%搞死,惨兮兮的~~~

(3)反外挂

    对于端游,外挂的出现速度快得叫你难以回应,而页游外挂一般都比较难检测,其中,比较有用的就是加速器外挂,检测到就直接踢掉吧。

(4)死连接

    死连接会造成拒绝服务,如果一个连接,一直连接什么事都不做,直接踢掉,不留情面

 (6)总结

    一套完整的游戏服务器,差不多就是上面那样子的。在早些时候,有很多游戏服务器是只有一个服,也就是逻辑服,我也搞过这种的,但是,在运行过程中,发现很多的不如意,首先是人数没有我想象的那么多,初期带2500人就差不多极限了,带不动了。最主要的表现是数据库写库很慢,还有日志是以log文件形式存在的,速度也很慢。还好后期人比较少,策划对战斗录像的需求也不多,勉勉强强撑了过来,又不就坑爹了。

    以上观点都是个人的一点愚见,希望对各位奋斗在游戏行业的朋友有所帮助,谢谢观赏。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值