如何设计属于自己的fps游戏服务器设计

如何设计属于自己的游戏服务器(一)
最近一直在做
的优化以及新功能的添加,不止一次有人在群里问我,你的这个PSS做游戏服务器怎么样?
确实,我也考虑过这个问题。无论自己的水平如何,好歹也在网络游戏服务器开发上走过8个年头了,从当年台湾第一的游戏橘子,到后来的自主创新的硅谷,到后来的搜狐,后来从搜狐出来又进入创业公司。
一步步的走来,很想写的什么。
最痛彻心扉的失败的游戏经历过,最激情的成功的游戏,海量玩家涌入的通宵也疯狂过。
看到很多做技术的朋友,对游戏还是趋之如骛,尤其是初学者,我想说,在你们开始你们的游戏服务器设计之旅之前,好好的让自己平静一下。
如果你不是为了争分夺秒或者急于成就自己的游戏,希望你可以静下心来读一下以下的文字。
在我这里,我会慢慢结合我的PSS来解释如何做一个,让你自己骄傲的游戏服务器。
前提是,你需要先静下心来。把以下的文字,转化为自己的故事。
这里,我并不会列举太多的代码。
因为我认为最不重要的,就是代码。
我会讲一系列的故事,希望这些故事,让你不断的从中吸收到属于你的东西。
诚然,当年的我,误打误撞的进入了网络游戏行业,说来也很奇怪,2002年的我毅然决然(或者说傻里傻气)从我的第一家任职的公司辞职,当时已经做到了公司的技术一把手。
但是不知道为什么,心里一直觉得这不是我的归宿,也没想这么多,就出来了,经历了三个月的煎熬,才知道自己的自大和无知。以为自己知识基类已经可以了,结果发现在别的项目上什么都无用。
于是明白了一个道理,任何时候,只要你敢于从零开始,永远会有所获得。
第一次参加游戏服务器的时候,并非我想的那么简单,虽然我已经做好了艰苦奋斗的准备,但是实际的考验还是大大的超出了我想象。
我和当时很多初学者一样,在网上大量搜索,大量买相关书籍,也经常问一些现在看来无所谓的问题。
后来慢慢的开发中发现,其实游戏服务器设计有几大误区。
你最不应该关心什么?
(1)现在网上很多的文章,尤其是关于游戏服务器的,都把网络IO讲的神乎其神,似乎socket效率就是服务器的一切,如果你读到这些文章,大可以建议你不用读下去了。
因为,网络IO是最成熟的,也就是说,代码换来换去就那么几行。如果作者用超过50%的笔墨再讲这些,只能说明作者本身对游戏服务器设计开发能力有限或者根本不想告诉你游戏服务器的设计核心在哪里。
实在是没必要浓妆艳抹,无论IOCP,epoll,还是kqueue。这不是你关心的事情,只要知道到时候用到的时候到哪里找例子就行了。
,这部分也不需要太多的介绍,因为数据库本身只是一个存储介质,用文件,用NoSQL,用DBMS,甚至用内存,这些都只是数据存于长久介质的一种方法。
数据库技术一样成熟,样例代码满天飞,不必要为此多花费精力。
(3)脚本语言,比如现在很多文章吹嘘Lua以及phthon等一些脚本在游戏服务开发中的优势,不可否认,这在某些情况下是非常优雅的。但是并不是没有这些,就做不了游戏了。
或者Java直接写的代码一样有优秀的游戏。
(4)网上相传的各种开源的游戏服务器,以及那些所谓“偷窃”出来的知名游戏服务器源代码。
这些代码实际完全无意义,除了多占据你的机器硬盘,没什么别的作用。因为对于初学者,在没有文档的情况下,去读动辄及万行的代码,实在是一件不靠谱的事情。
你应该关心什么?
(1)你的游戏服务器要达到什么功能?
每个策划给你的需求都不同,你要知道,你的游戏特点是什么?理解在这个特点上,我们的卖点是什么?那么,为了这个卖点,我们怎么保护核心玩家在一定程度的核心体验。
(2)服务器的初步布局如何?
你可以采用什么样的游戏服务器布局,单机,一组?还是集群?
在这个布局下,划分每个功能在每台服务器的应该完成的任务。这里先不需要去想代码。
你能够用你的铅笔和纸张画出主要数据流动方向以及服务器主要功能分布即可。
(3)你手里有什么资源可以支持你的?
成本非常重要,要知道商业活动,都是要最小化成本的,不可能为你的一个游戏搞个几十台服务器才支持2000人。
所以了解自己有什么非常重要。
(4)你的同伴有什么擅长的技能和技术方向?
这一点至关重要,你的下属或者同伴,如果你让他们做自己不擅长的事情,肯定会增加成本而得不偿失。
(5)你的时间预估如何计算?
如果你预计某一项功能大概需要5天/人,那么保守的估计你最好乘以一个1.5的系数,还有懂得,什么时间做什么事非常重要。给自己设置阶段里程碑。
这里只考虑功能主模块的时间。
如果你对某一项技术不熟而需要技术预研的话,这段时间不计算再开发周期内。
设计一个好的游戏服务器,需要的不止是技术,最重要的是一个好的规划。有好的规划,就是成功的一般。
代码只是实现体,实际重要程度并非主要。
如果在你的开始设计上出现了问题,那么,后期游戏服务器就会花费巨大的成本修改前期的错误。
好,下一讲,我会讲如何利用PSS去设计你的游戏服务器。
有一个概念必须先入,不要陷入代码的海洋,你应该能抽出身来,如果你不能用简单的语句描述清楚你的需要,就不要动手去实现你的代码。
& 2012 - 2016 &
&All Rights Reserved. &
/*爱悠闲图+*/
var cpro_id = "u1888441";-1岁的游戏服务器设计 - 简书
-1岁的游戏服务器设计
最近调研了一下游戏服务器设计的问题,周末花了些时间查阅相关的书籍和文章,也了解了一下Photon、KBEngine、Skynet这些开源游戏服务器的结构和实现,边学习,边整理。
Web服务器设计
在思考游戏服务器设计的时候,我首先想到的是一般Web服务器的设计结构。最简单而典型的Web服务器模型可以总结为:
服务端创建一个监听Socket持续等待新连接,客户端发起TCP连接,然后三次握手成功建立连接。接着客户端(浏览器)发送HTTP请求给服务器,服务器返回HTTP响应回复,并在客户端呈现用户想要的内容。
在这个基础上,再进一步,如果是运行有Web App应用的服务器,则会加入Web框架,来进行多个应用模块的管理、使用及调度,例如python中的Django、Flask都是优雅而易用的框架。如果在一个服务器上需要运行多个框架及应用的时候,会考虑在服务器和框架之间加入中间件组件,它可以根据目标URL将请求消息路由到不同的框架应用,也可以进行负载均衡,例如针对python的WSGI接口设计。在这种情况下,Web服务器模型可以总结为:
服务端监听客户端连接,客户端发起连接,创建连接后,客户端发送HTTP请求给服务器。中间件通过消息路由、转发请求找到框架,提供可调用的应用。服务器调用可调用的应用,处理接收到的HTTP请求。框架/应用产生HTTP状态和HTTP响应头和响应体传递给服务器。由服务器组装成一个完整的报文返回给客户端,并在客户端呈现用户想要的内容。
在此基础上更进一步,大型的Web网站和动态应用,我理解的服务器设计就是指后台整体设计了,包括:
基础服务器配置(Apache、Nginx)
Web应用框架和中间件
数据库IO(MySQL/Oracle/MongoDB、优化存储、读写分离、负载均衡、数据与应用分离等)
缓存系统(常分为文件缓存、内存缓存和数据库缓存,在大型应用中使用最多且效率最高的是内存缓存,现在常用的内存缓存工具有Memcached和Redis。而且现在大家都比较关注图片缓存优化,常常有专门针对图片的服务器设计)
分布式存储系统(Hadoop、Spark、HBase对这方面还不熟)
分布式服务器管理系统(批量化的任务执行、配置文件、命令管理、脚本程序、补丁安装等等,运维的工作)代码发布系统(生产环境下以虚拟主机方式提供,源代码管理和版本控制,集群间代码同步,参与内部开发、内部测试、生产环境测试、生产环境发布4个开发阶段的管理)
游戏服务器设计
Web服务器的设计大概可以这样去划分。那么游戏服务器和Web服务器又有什么样的不同呢?
首先,根据前面的描述,一般的Web Application,是典型的Request-Response模式,通过TCP和服务器建立短连接,而请求数据和影响数据通过HTTP协议进行组装,当完成交互的时候,服务器端和客户端TCP连接就会释放,把服务器端socket资源留给新的客户端。游戏服务器最大的特点是多数要求通信的实时性,客户端和服务器端通常采用长连接(并非绝对),客户端会主动给服务器发送数据,服务器也可能主动往客户端发送数据,生命周期比较长,一次发送的数据量比较小,但是数据交互发送比较频繁。由于要进行长连接,服务器端的socket就不能进行复用。其次,在web程序中,客户端之间的数据是没有交互的,所有的数据都是通过web服务器响应给客户端;但是网游服务器中,每个客户端的数据的变化,都要通过服务器端广播给其他客户端进行同步。所以客户端会有上限,同时服务器要进行分区,一个区里面同时在线人数会有限制。
除了这两方面不同外,其实很多Web服务器的设计方法是可以应用到游戏服务器上的,下面是我设想的一种游戏服务器设计:
一种MMORPG游戏服务器的设计.png
关于这个设计的说明:
网关服务器:负责监听和维持客户端连接,数据发送到游戏逻辑服务器,客户端和游戏服务器之间的消息转发和加密解密,没有具体游戏逻辑,可能需要设定连接数量。
游戏服务器:游戏进程实现,负责提供游戏逻辑,与数据库服务器通信负责数据交互。一般单进程或单线程模型可以应付,有的采用其他解决方案(比如Photon的纤程)。这里采用多个游戏服务器来模拟多个区服情况。
数据库服务器:专门用来处理与数据库的连接、查询、数据存盘等操作。方便游戏服务器异步读写数据库的数据。
管理服务器:有点像混合P2P通信里的中心节点,负责管理所有的游戏逻辑服务器以及他们之间的之间消息转发,提供广播到所有游戏服务器的功能。
战斗服务器:考虑到多人MMO同步操作的实时性要求,是否需要单独设计这么一个部分不是很确定。
数据库目前一般是在关系型数据库mysql和非关系型数据库mongodb两者中选型。数据库写操作采用周期存盘方式,每隔固定时间存盘一次,比如10秒或者15秒,减小数据库压力。采用Memcached或者Redis分布式内存缓存方案来减少读数据库的压力。
通信协议客户端与服务器之间协议通信,弱联网手游,一般采用http协议通信即可。大型MMORPG网游大多数都采用TCP协议或者HTTP和TCP结合,客户端和游戏服采用http协议。多人战斗情况下与战斗服通信采用tcp长连接。用UDP的情况主要是为了提高通信效率,需要自己做丢包重传和组装、校验的工作。服务器之间通信可以采用目前较为流行的ZeroMQ消息队列,然后也有很多优秀的开源通信库可以用来实现通信协议。
开发语言 业界主要的是c/c++ + python/lua模式做游戏服务器。c/c++做网络通讯数据传输,python/lua做业务逻辑。这样既保持了网络传输的效率(c++),又提升开发效率(python/lua),同时也支持热更新。
protobuf:google提供的序列化和反序列化组件,将自定义类型的数据转化为二进制序列传输。优势是对于传输比较大的数据产生的数据很紧凑很小,可以明显减小传输量。而且处理速度也比较快,又有各种编程语言的实现,例如C++,Java,PHP等等。缺点是不能明文编辑(数据是二进制的)。用protobuf rpc进行数据传输很方便,但需要自己实现。
ZeroMQ:稳健,简洁的多进程消息队列实现方案。ZeroMQ 不一定基于 TCP 协议,它也可以用于进程间和进程内通讯。在这里它更适合服务器与服务器之间的通信,逻辑服和战斗服之间的通信。
memcached:高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,不需要每次操作都访问数据库,提升性能。基于http协议的通信可以用memcached,如果是tcp长链接,就维护一个在线的内存对象。类似的技术还可以考虑redis等。log4net/glog/zlog:日志记录组件。定义好日志级别:error / debug / fatal / info,做好时间戳。
一些服务器框架
最后,附上一些目前正在进行,而且应该今后较长一段时间都会在看的一些优雅而易用的服务器框架吧::目前在Unity 3D手游方面用的最广泛的服务器框架,支持部署自己的服务器,Photon也有提供云服务器。运行于Windows平台,底层C++实现,上层采用C#作为开发语言。更多的关于Photon的内容在。():同样应用于Unity 3D的网游开源服务器框架,C++ + Python的模式,文档和视频教程还比较全。有一个不错的可以学习。()9秒社区开发的一款基于python的游戏服务器框架,刚出来不久的小鲜肉。: 国内的游戏开发大神云风写的一套基于Actor并发模型的服务端底层管理框架,看了一下,不得要领T_T。:基于python的Web开发框架,被Facebook、知乎和豆瓣采用。特点是实现异步非阻塞的I/O模型。因为这个模型和Unity 3D中的协程很像,所以挺有兴趣。
可能随着以后对于服务器开发的深入实践再回头看这篇文章会发现很多幼稚和错误吧,不过偶尔思考和实现这些像模型一样的设计的东西也挺有趣的。很多游戏都在花费大篇幅讲解网络模型,其实,这些对于你而言,完全不必关心,现有的模型一大把。就比如PSS,你用它就可以忽略网络IO模型,直接负责处理到达的数据和如何回应就行了。
那么,我们来说说游戏的一些细节。
以端游为例,现在的端游可以说各种花哨,各种副本,公会战,任务,锻造,跑商等等等等。。系统繁多。
但是请静下心来,拨开那些层层迷雾。
其实游戏服务器没什么神秘的,就几个专业的可能比较耗一些功夫,比如,AOI,比如,寻路,比如,脚本。
先不要去想这些实现手段,首先要知道,我们有什么武器?
无论任何游戏,都分为两种消息,一种是客户端主动提交给服务器的,一种是服务器主动下发给客户端的。简单的来说,无外乎,一去一回,一回一去,一去,一回。
一去一回,就是客户端主动发起一个事件,需要得到服务器的回应。
一回一去,就是服务器有事件发生了,需要通知客户端。
一去,客户端只是通知服务器一个事件。不需要回应。
一回,服务器通知客户端一个事件,不需要回应。
很好,先明确这个概念,也就是,服务器和客户端之间的通讯,是一种或者几种事件机制。
网上一些说游戏服务器的文章,说每秒吞吐几万个数据包如何如何性能了得,我很想问问,实际的游戏服务器,你真需要这么大的服务器吞吐量吗?
当然,你可以说,像Dota,星际那种实时对战游戏,对数据包有及是毫秒级的要求,毕竟人家讲的是DPS。但是,我想说的是,大多数游戏,根本不需要这么多的数据包吧。
很多时候,设计是可以优化的,如果我是一个玩家,1秒钟内在地图点击了10个地点,如果控制的小人都去那些地方,光服务器和客户端来回耗时就会很多。先不谈网络优劣的问题。问题是,这些数据有必要服务器去处理吗?
(1)必须先明确,什么是无效的数据和事件。
对,什么是无效的数据。无效的数据很空泛,其实从用户行为分析,你可以分析出用户在你的游戏中,哪些是属于无效操作。客户端主动屏蔽这些无效操作。比如,1秒钟我换了10个方向,那么我只需要取得最后一个防线即可。也就是前9个我完全可以忽略。当然,客户端需要处理一下这为展示。再比如,我反复的打开了商店界面,因为商品在一定时间内是稳定的,那么完全可以过一段时间同步一下商店数据即可。不用每次都发送请求。
不过从实际运行来看,并不是说客户端屏蔽了这些无效操作就可以了。服务器一样要做这些动作,因为你无法约束数据包行为。或许外挂,特殊情况,会有垃圾数据包到来。
就好比,你把服务器看做一个餐厅,进来一批食客,其中保不齐有周围餐馆派来砸场的,你的厨师就那么几位,有些人故意点了一大桌子不吃,害的你的厨师忙死,却让真正想吃饭的食客等不及而离场,这明显是得不偿失的。所以,你的服务器需要一个经验丰富的&侍者&,它可以分辨食客的点餐餐单,那些是有明显问题的,比如,有i一个食客连续点了10个宫保鸡丁,你就要看看这个食客到底是要干什么。
服务器的这个&侍者&,就是要对客户端上来的各种&餐单&(数据包)进行初步过滤,起码,不能让那些明显处问题的餐单来占据你的服务器资源。
从设计的角度来讲,我可以对某一个用户的数据包进行归类,某一类数据包不能短时间出现多次。如果出现了且非要回复,只取得在这段时间内最新的一个即可,其他的同类数据包丢弃。
我这里要讲一个设计关键原则,就是一定要保证优质的游戏玩家享受最好的服务,而那些质量差的玩家,很少会为你的游戏多付费,所以,想办法保证一切优质客户很重要,服务器的资源也应当倾向于此。
(2)那些是必须现在返回的,哪些是可以等一会再返回的。
很多网络讲游戏服务器的文章,更加更关注的技术的实现细节,而实际上,我们跳出这些繁复的代码。仔细分析一下?哪些是 &立即&和&暂缓&。
还是拿餐厅举例,一般人气火爆的餐厅,大多不会一个客户点一个菜立刻抄一个。抄完了在看下一个餐单。
而是,会等那么一小会,看这一小会会不会有相同的餐单到达,一锅烩,一起出盘。
别小看餐厅的学问,好好的和他们学习,你会学到非常多的服务器设计知识。而且,好的餐厅往往能教你怎么做一个伟大的服务器。
那么,你看,这些餐单,实际是可以&等那么一会也没什么大问题的&。
而有些则是必须马上返回的,比如,食客下了餐单,你必须交给厨房以后迅速的告知食客,你的餐单已经到达了厨房。
拿游戏中的一个实际功能来说,玩家发出一个&行走&指令,实际上,客户端已经可以行走了。服务器只要返回一个收到了即可。只要定时计算服务器和客户端的玩家点位是否匹配即可。有差距拉回来。
而对于服务器,完全可以等那么一等,比如,等1秒,这1秒钟所有的玩家行走指令都收齐了,一个定时器一口气算出来。
或许就有那么讨厌的玩家,连续1秒钟换了3,4个终结点。
换个话说,有哪些餐馆讨厌的食客,刚下单就要换菜品,犹豫不决,如果餐厅没有这个&缓冲&时间,那么做出来的菜谁去消费?明显是浪费食物。(浪费服务器资源)
还有就是,游戏中的交易,必须时时反馈,交易成功了还是失败了,必须第一时间让玩家知道。
餐馆也是这样,结账的时候,食客提出刷卡,如果服务器员说你等会,等到一波食客一起刷,人家不骂你才怪。
所以,从设计上来讲,要学会细分这两项,仔细想清楚,会给你的服务设计带来非常好的体验提升。
(3)如何规划数据流
还是拿网上的文章来说,很多文章在游戏服务器上推崇。
多线程,对于初学者总觉得会很快,而当实际使用的时候,总是发现各种数据需要再不同的线程里同步的问题,造成大量的数据锁,代码复杂了不说,自己估计以后都难以看懂。
所以,这里要说,组织多线程是一门学问。
还是那个餐厅。
我有10个桌子的食客,其中6个点了甜点,有4个点了鱼肉,有7个点了小吃。
如果让一个厨师去做这些菜。肯定会慢的出奇。
看看现实中是怎么解决的?有甜点师,有配菜师,有几个大厨,分别应对不同的菜品。同时去做,各自互不干扰。做鱼的不用知道食客点了多少甜品。
那么,游戏服务器是怎么表现呢?
我有一个玩家进了一个场景,那么理论上,一个场景内,只有这个场景内的玩家会对他产生影响。别的场景都可以不用知道这个玩家的存在。
那么,如果把这个场景看做一个厨师,那么&玩家&实际就是一个个餐单。不同的厨师去料理不同的餐单即可。菜可以同时上,也可以一个个上。
实际上,90%的多线程数据锁,是完全可以用这种或者那种数据模式去解决的。
大自然教会了我们如何生存,也教会了我们,如何用这些规则造福别人。所以,很多程序设计上很难的问题,实际你的生活早就教给了你解决方法,关键是,要学会去发现,去思考。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:13386次
排名:千里之外
原创:23篇
评论:11条}

我要回帖

更多关于 游戏服务器架构设计 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信