程序员
游戏开发
游戏公司
服务器
游戏服务器开发

游戏服务器与普通服务器有什么区别?

相比于我们常见的数据中心的普通web服务器,游戏服务器(如英雄联盟,魔兽世界)有什么特别的地方?
关注者
2,245
被浏览
630,238

88 个回答

web、app服务器和游戏服务器都做过,说说我理解的区别吧。

如果是同等用户规模,相对来说,游戏服务器的复杂程度要大于普通app和web服务器。当然涉及到特殊算法的服务器另说,比如搜索引擎、头条人工智能推荐这些除外,在这里只说普通的。

游戏服务器根据不同的游戏类型有很大的区别,如王者荣耀之类的MOBA手游,服务器主要由2部分构成,局内战斗服务器和局外系统服务器。

局内战斗服务器程序是游戏专用的,在其他app服务器上几乎没有使用场景,在技术方面是有鸿沟的,也就是说你在开发app服务器上使用的技术以及设计思路,是无法转换为局内战斗服务器设计思路的,两者之间存没有相同点。

战斗服务器需要做到给各个玩家数据同步,也就是说,在一局游戏内,所有玩家的实时状态都要相互可见。这其中又设计到2种技术,帧同步和状态同步。

帧同步服务器不包含游戏逻辑,就是简单将客户端发送过来的命令转发给其他客户端,比如玩家A执行一个攻击操作,那么玩家A客户端会给服务器发送一个攻击命令,服务器将这个命令同步给局内的其他玩家,至于攻击一下少多少点血,会不会把人打死,服务器不管,全部由客户端完成计算判断,客户端计算完毕后将结果发送给服务器,服务器再将结果同步给其他玩家,然后客户端播放表现效果。简单的说帧同步服务器就是给各个游戏客户端同步数据,它会不间断的发,即使局内的玩家什么都不干,傻傻的站在那里,服务器也会发,他的作用就是同步玩家们的状态,所以说帧同步服务器费流量。

状态同步服务器和帧同步服务器的区别在于,除了同步玩家状态的机制相同外,状态同步服务器包含游戏的运行逻辑,比如玩家之间互相攻击、技能伤害大小计算,都在服务器上执行,然后再将执行结果同步给客户端,客户端只要根据结果播放对应的动画就可以了。

简而言之,帧同步服务器和状态同步服务器的区别就是游戏局内游戏逻辑放在哪儿运行的问题。因为要运行游戏逻辑,状态同步非常消耗服务器资源,如果代码写的烂一点,一台4核8G的机器上只能跑10局游戏100个玩家,那么要是同时有10万玩家在局内,就需要1000台服务器,这么多服务器,运维管理压力非常大。因此使用帧同步服务器能有效的减少服务器消耗资源,减少服务器数量。然而有缺点就有优点,因为业务逻辑在客户端,帧同步服务器很难有效的杜绝外挂问题,断线重连也相对费劲,用户体验差。而状态同步则不存在这种问题,能有效的杜绝外挂,也能很容易的支持重连进入游戏。所以这两种技术各有优缺点,选择哪一种,需要根据实际情况权衡。

普通的web服务器或者app服务器十有八九使用基于tcp的http协议,而局内战斗服务器,普遍使用UDP。TCP是可靠传输协议,用起来省事,确认机制、丢包重传、滑动窗口之类机制开销也大,在极端性能敏感的场景下,裸奔的UDP更加合适,通过UDP实现一个lite版的TCP,是游戏战斗服务器常规的优化手段。

不过话说回来,看起来局内战斗服务器实现有很多门道,但是工作量其实非常少,属于做好一次到处通用, 即使状态同步,虽然业务逻辑跑在服务器上,但实际功能开发还是客户端程序员实现,服务器只是提供了一个运行程序的容器,战斗逻辑的实现不归服务器管。

再说说局外服务器,这部分和普通的web服务器和app服务器就比较像了,MySql、Redis、protobuf、消息队列、分布式框架等等互联网应用的基础架构在游戏服务器上也是常规配置,不过有一点明显的区别是,游戏服务器的数据存储都是以玩家为单位的,当玩家登录的时候,程序会将所有玩家的数据,如道具、装备、任务等所有相关数据从MySql等数据库中加载到程序内存,之后所有的操作都在内存中进行,之后等到某个适当的时机才会将内存中的数据同步到MySql中。当然,为了保证即使程序挂掉,数据也不丢失,还需要设计许多复杂的机制,这里就不展开了。

而web服务器和app服务器则不是这么设计的,因为游戏如果不登录是不可以玩的,因此我们可以把数据结构设计成以用户分组的。而web和app即使用户不登录,功能依然需要可以使用,功能和用户不绑定,所以设计的时候也不会把数据以用户为单位进行组织。不过除了数据组织方式不同外, 其他地方大致都相同,原本是做游戏服务器的,稍微熟悉下就可以去做web或者app服务器,反过来也一样,互相之间没有门槛。

不过从技术的角度出发,局外游戏服务器的技术相对与其他互联网行业是比较落后的,如果你原本是在传统互联网行业,转去做游戏服务器,可能会被雷到,因为他们用的框架一点也不”现代化“,也许框架的性能还不错, 但是开发效率极低。这一点和游戏客户端不一样,游戏客户端是脱离传统互联网技术的,他们有自己的技术栈,而且实时更新。比如unity、unreal引擎出新版本了,他们都会讨论的热火朝天,然后尝试升级使用,这和互联网行业的vue、react、spring更新一样,相关程序员都会热衷与研究。

但是服务器却没有这样的热点可以追,我在一家公司,这家公司虽然已经生产了几十个游戏,客户端引擎也不知道换了多少套,但是服务器程序却一点没变,仍旧使用祖宗流传下来的那套c++框架,里面什么都是手动实现的

比如数据传输协议,是自己组装字节流,发送给另一端,另一端根据事先定义好的规则,一个int,一个bool,一个float的读取。这对于理解网络的本质非常有好处,但是显然在实际应用中,使用protobuf会更好。

当然我也碰到过协议不自己实现而是使用protobuf的,而且使用的是java开发局外服务器,而网络底层仍旧使用java自带的NIO,而不是更好的netty。

总而言之,传统的游戏服务器程序不是太喜欢用框架,而是偏向于自己造轮子。这可能跟这个行业大量使用c++有关系,即使有一部分游戏使用java服务器 ,但是开发人员大多也是c++转过来的,还是以c++一切靠自己的思路在开发,所以很难见到流行的互联网框架在游戏服务器上使用。

游戏服务器不会只用一种语言开发,也可能是两种。如果是一种,那大概率是c++。如果是两种,那大概率是c++加另一种语言。

用c++的原因很多,如果要找一种语言,兼顾性能、开发效率、流行度,那肯定是c++。战斗服务器通常用c++开发,一来是速度够快;二来战斗程序通常需要同时在客户端和服务器上运行,要找一种跨平台的,还是要c++,比如unity种就可以通过c#调用c++。

局外服务器可以不用c++做,用java、go甚至php都可以,不过近年来用go好像越来越多了。

最后还有一个人员方面的区别,一个传统互联网项目,后端开发人员会多于前端开发人员。而一个游戏项目,客户端开发人员要比服务器开发人员多,可能一个项目服务器程序员只有3个,而客户端程序员有10多个。而且客户端程序员都很忙,而服务器程序员,在开发阶段,相对很闲,游戏上线后, 会忙一些。

编辑于 2021-12-22 10:07

一般的网站应用程序,是典型的Request-Response模式,通过tcp和服务器建立一次链接,而请求数据和影响数据通过http协议进行组装,当完成一次交互的时候,服务器端和客户端tcp链接就会释放,把服务器端socket资源留给新的客户端。通常web程序是比较好扩展的,通过硬件负载均衡和添加web服务器来实现,这一套方案业界都已经比较成熟了。网游比较特殊,最大的特点在于客户端和服务器端是要进行长连接的,客户端和服务器端基本上一直要保持连接,不是典型的Request-Response模式,Client会主动给Server发送数据,Server也可能主动往Client发送数据,生命周期比较长,一次发送的数据量比较小,但是数据交互发送比较频繁。由于要进行长连接,服务器端的socket就不能进行复用,单台服务器处理请求是会有限。用web的方案解决扩展问题,也不太适用。在web程序中,客户端之间的数据是没有交互的,所有的数据都是通过web服务器响应给客户端,但是网游服务器中,每个客户端的数据的变化,都要通过服务器端广播给其他客户端。所以客户端会有上限,这也就是为什么服务器要进行分区,一个区里面同时在线人数会有限制。

发布于 2014-04-23 09:32

朋友里有一位服务器大牛做过类似的总结,我征得他的同意把当时的资料分享一下。大量删节。

文章里说游戏服务器比较多,没怎么说web服务器。但是看了之后你就明白Web和游戏服务器在并发性方面根本性的不同了。

游戏服务器架构通识

· 前言

· 我们将从游戏服务器发展的简单历程出发,鸟瞰一下目前大多数的游戏服务器架构。

· 这里尽可能的避免陷入细节的技术问题,而是从技术进化的结果状态,反推原始问题是什么。希望能通过这个过程,解释清楚游戏服务器是在解决什么问题,痛点到底在哪里。

· 一、早期网游服务器。




· 蛮荒时期的游戏服务器框架我们一笔带过,那时的游戏服务器和一个小Web服务没有区别。

· 蛮荒时代的服务器只负责存储玩家账号、数据、转发场景内其他玩家的行为。很多移动、使用技能等关键逻辑在服务器上根本没有。随意就能用变速齿轮改变游戏速度。

· 从传奇的时代开始,游戏服务器就不再是简单的上传存档、下载存档、访问页面而已。游戏服务器内部出现了游戏逻辑,既能用于同步每个玩家看到的世界,又能让逻辑与客户端分离,避免早期的网络游戏那种毫无防范的逻辑体系(对外挂防御能力为0)。

· 这种架构奇怪的地方是处理网络连接数据传输的压力和逻辑处理的压力在同一个服务器上(存储模块可能也在同一个进程),就算逻辑处理压力为0,承载人数也高不到哪去。

· 二、早期游戏服务器的改进版本

· 当开发者们有了初步经验以后,新作品的开发,自然而然的过渡到了如下的形式:



· 游戏逻辑服务依然是在一台服务器上,单进程(逻辑处理本身肯定是在一个线程中,可以有子线程负责内网通信)。但是我们自然的想到,存储负载和网络连接负载可以从逻辑服上拆出来。

· 由于连接服务器本身没有时序性,很容易做分布式的(其实大部分游戏还是只用一个连接服),存储服务不要求高实时性,高峰期存盘间隔可以稍长一些,不会对游戏服造成影响。

· 三、成熟形态的服务器框架(这节是重点)

· 1、逻辑服务器的负载均摊方法一:按照功能划分多个服务器进程



· 2、逻辑服务器的负载均摊方法二:按照场景划分多个服务器进程



· 难点在逻辑的设计上,要像做手术一样把本来是一体的功能切开,并抽象出若干个API来保持联系(服务器之间是TCP连接)。

· 在分解时,要找联系相对最薄弱的环节入手,比如场景和场景之间分开、单独抽出聊天服务、组队服务、好友服务。

· 无论如何分解,最终结果只能是有限个服务。而且分解的越细,开发难度就越大。因为跨服务器逻辑是把简单的同步逻辑变成了异步Callback逻辑,而且容易出现时序问题等不易测试的问题。

· 单个场景服务几乎是无法分解的。分解单个场景难度巨大以至于出现了BigWorld引擎来专门的解决场景分割问题,后面会谈到。

· 这种成熟形态的游戏服务器已经能满足现实中99%的频繁交互类网游需求,是大型MMO端游、页游的主流形式。

· 对比Web服务器

大致只说一点:由于数据库的存在以及HTTP请求的特性,Web服务器天生就是并发的,也一直在高并发的路上越走越远。


· 附:开房间式的网络游戏


· 开房间式的网络游戏也是游戏的一个重要分支,英雄联盟、DOTA、很多手游例如皇室战争、王者荣耀等等。

· 这种游戏房间之间几乎没有交互,只有大厅内有交互,可以理解为原始形态的游戏服务器的平行扩展。

· 房间式游戏扩展难度较小,只是需要根据玩家数量动态扩展游戏房间的数量、服务器数量。很像网站的架构。

· 这种游戏架构最最适合放在云平台上,设计合理的话,它可能遇到的问题和大型网站几乎一模一样。不需要特别的讨论它们。

· 只是,毕竟游戏不都是开房间的玩法。

· 小结:游戏服务器框架特点

· 1、真正的数据都在内存中,数据库性能不那么重要

· 注:很多大型游戏采用了共享内存,避免宕机时损失过大。

· 2、单CPU性能比CPU数量重要的多。

· 3、目前有很多游戏,特别是手游,使用Redis读写代替内存读写,甚至也有用Mongo的。

· 4、开新服、旧区合服的情况,非常适合云平台。

· 先进服务器框架

1、BigWorld。理念过于超前,把并发性做到极致,开发友好度弱到极致,已废。

2、Skynet。本人强烈推荐,谁学谁知道,除了必须要用lua语言,没有什么缺点。


· 聊聊十万行代码

· 游戏服务器开发速度受美术资源制作速度、客户端开发速度制约。近几年我猜测服务器方面并不会有大的技术革新。

· 游戏开发未来的趋势是多元化、低门槛化、大众化。很长一段时间内BigWorld这种大怪兽级别的引擎不会再崛起。

· 分布式框架的崛起时间点,无论如何,也在VR技术成熟之后了。

编辑于 2021-02-18 14:11

实名赞同

@DalYz

的回答

补充一个资料:

深入剖析MMORPG游戏服务器端的设计

 MMORPG不同于其它的局域网的网络游戏,它是一个面向整个Internet的连接人数过万的网络游戏,因此他的服务器端设计则极为重要

服务器的基本设置

  在大型网络游戏里,通常设计为C/S结构,客户端不再对数据进行逻辑处理,而只是一个收发装置,从玩家那里接受到操作信息,然后反馈给服务器,再由服务器进行处理后发回客户端,经客户端通过图形化处理,给玩家呈现出一个缤纷的游戏世界。


  登陆服务器

  在这里也可以称之为连接服务器,网络游戏的客户端一般是连接到这里,然后再由该连接服务器根据不同的需要,把游戏消息转发给其它相应的服务器(逻辑和地图服务器)也因为它是客户端直接连接的对象,它同时也负担了验证客户身份的工作。

  地图服务器

  在这里也可以称之为连续事件服务器。在这个服务器里要处理的对象(玩家)所做的动作都是一个连续事件。例如玩家从A点移动到B点,这样一个动作,需要一定的时间进行移动,因此说移动是一个连续事件。

  逻辑服务器

  在这里可以称之为瞬时事件服务器,在这个服务器里,处理对象(玩家)所做的动作均可以在非常断时间内完成完成。例如玩家从商店购买一瓶药书,当玩家确认购买后,服务器先扣除玩家的游戏币,然后再把相应的药水瓶加入玩家的背包里。这2个操作对于服务器来说,只是2个数字的加减,计算完这两个数字的加减,这个事件就可以结束了。因此,我们可以说这个事件是一个瞬时事件

服务器组的改进

  不过在实际应用的过程中,游戏服务器的结构要比上面所说的3种服务结构要复杂些,不过也都是在这3种最基本的服务器架构下进行扩充,扩充的主要是其它辅助功能。在实际应用里可能增加的2种服务器,数据库服务器,计费服务器,由逻辑服务器独立出来的聊天服务器。


  数据库服务器

  数据库服务器其实就是专门利用一台服务器进行数据库的读写操作。这点特别是在大型的网络游戏里尤为重要。因为在大型网络游戏里,要处理玩家的数据量非常大,如果不利用专门的服务器进行处理,很有可能会拖累这个服务器组。

  计费服务器

  通常在商业的网络游戏里出现,用于记录玩家在线的时间,给收费提供依据,同时也是整个服务器组里最重要的部分,一旦出现问题,运营商就不用赚钱了。

  聊天服务器

  在游戏里的聊天功能是属于一种瞬时动作,理论上是放在逻辑服务器里进行处理。不过在大型网络游戏里,因为这个部分功能与游戏里的其它部分联系并不紧密,因此可以独立出来做一个功能服务器。

服务器的集群设置

  在大型游戏的应用过程中,实际需要处理的玩家数量可能过万,一台普通的服务器是无法完成所要完成的工作,因此,在实际应用的时候,通常是由一组多台服务器共同完成一个功能。

  例如地图服务器,可以根据需要,把游戏里所有的地域进行划分,划分为N个区域,然后让这一个区域里发生的事件都用一个特定的服务器进行处理。这样做的目的是减少一个服务器所承担的计算量,把整个系统组成一个分布式的网络。

  不过这样做的同时会造成一个麻烦:当一位玩家从区域1,移动到区域2。这个时候,就必须先在服务器1里把玩家删除,然后再在区域2里加入玩家。同时需要由服务器1向服务器2转移玩家的数据信息(因为服务器组在工作的时候,玩家的信息只能保存在当前所在区域的服务器里),也就是说一旦玩家发生服务器间区域移动,服务器端就不可避免的造成数据通讯。因为这种移动并不是有规律的,玩家所在的服务器都有可能到达其它服务器。这样,如果服务器组里有N台地图服务器,那么,每个服务器都可能向其它N-1台服务器产生连接,总共就可能产生N×N个连接。如此数量连接如果只是使用普通的socket设计,就很有可能会给服务器通讯间的各种问题所困扰,为此,在商业网络游戏的服务器之间,通常都使用成熟的第三方的通讯中间件,如ACE,ICE等作为网络连接的传输层。

发布于 2015-10-04 20:20

最大的区别是,web服务器每个client都是独立的,游戏服务器不同client是有交互有状态,会实时地互相影响。这导致很多设计上的差异。

并发架构的影响

在高并发下,对client请求进行负载均衡并不如web那么简单,因为client状态会互相影响,并且可能共享写数据甚至有时序依赖。大型mmorpg通常是长连接,并发服务数通常要远小于web服务器 。根源就是实时性和强交互性的限制,两者要求越低的游戏,并发就可以做得越高。

web服务运算较少,io密集,读多写少。游戏服计算和io都密集,读写都频繁

对代码风格的影响

比如开发web服务,基于nginx的openresty就很好用,利用了Lua的协程和异步io,写起来很流畅而不失性能。但用来做游戏服务器,协程却可能是个坑,因为游戏依赖很多上下文环境,当协程被唤醒时,上下文环境改变,协程的代码风格很容易用了旧变量导致逻辑错误。

编辑于 2015-07-21 22:20

做过游戏服务器的开发,也做过一般的互联网服务器的开发,在我看来两者的区别主要有两点.

1)游戏服务器比一般的服务器要保存更多的状态:玩家的属性这些自不必说,一般的IM服务也会有,还有一些马上就会变化的数据,比如某个玩家的生命值,发技能前后的法力值等等,这些值区别于一般的属性值如名字,ID这些的差异在于,会经常性的变化,还会参与到逻辑的计算中,比如你一个多少等级的玩家吃了什么东西之后战力值变化为多少,打在一个多少属性的玩家身上会不会被他闪避,会不会产生暴击....

游戏逻辑中的战斗技能计算是很大的一个点,我不太熟悉这块就不展开多说了.可以看到,游戏逻辑的CPU计算是非常多的.

2)游戏服务中,每个玩家不是独立存在的,而是很有可能会与其他玩家发生状态的交互,一般的服务器比如HTTP什么的,你一个请求过来查你的数据,和别人的请求是独立的,并没有什么交互.

客户端之间会有交互这一点,举最简单的例子,一个人在一个场景里面说了一句话,那么同一个屏幕的玩家也需要能够看到他说的这句话.此时游戏服务器就需要判断,多远的距离以内的玩家,会认定为是"同屏幕"的玩家,需要向这些玩家广播这个玩家说的这句话.

这个广播就比较麻烦了.首先,计算哪些玩家在"同屏幕",就是我们在第一点提到的玩家身上某些经常变化的属性需要做的运算,在这里需要根据玩家的坐标,找出来跟在同屏幕的玩家,用到的是AOI的概念,感兴趣的可以看看

云风的 BLOG: 开发笔记 (13) : AOI 服务的设计与实现

.另外,找到了这些需要接收这个消息的玩家之后,将消息转发给它们又是一个IO密集的操作,假如场景中有10个人,那么一句话就需要同时广播给另外9个人,假如有100人,1000人呢,量就更大了.所以同样的一个硬件配置的服务器,可能跑Nginx可以同时处理上万的链接,但是对于一个游戏服务器就只有1,2千了,就是因为游戏服务器是一个CPU密集而且IO密集的服务器类型.

发布于 2015-11-09 23:24

综述

早期互联网基础硬件设施与网络软件技术不完善,存在数据存储量少,传输速度慢等特点,在加上早期显示技术只支持文字显示,所以早期网络游戏是一些交互性弱,数据量少的文字交互游戏。但随着图形界面技术和互联网技术的发展,网络数据存储量和传输量增大,出现了多种多样的游戏,相应的服务器技术也越来越复杂。

本篇文章主要分为两个部分,第一部分是服务器历史和现在,这部分主要是房间型服务器架构的由来,主要目标是让大家知道现代服务器架构各个组件的由来以及作用,知道服务器怎么从之前的单服务器架构发展成现在复杂的多类型服务器架构,发展图如下。

游戏服务器发展史

第二部分是服务器的未来,这部分的主要内容是游戏如何上云、什么是云游戏以及云游戏工作原理。从服务器历史发展可以更好的理解现在服务器架构组成,同时也可以看出游戏服务器未来发展趋势。服务器发展趋势主要取决于玩家游戏需求以及上下游技术产业链。目前来看:游戏内容的越来越精细,互联网传输量的越来越大以及云计算的发展壮大,个人认为未来服务器发展是游戏上云以及云游戏。

文章目录:

  • 单服务器进程
  • 多服务器进程
  • 多类型服务器进程
    • 数据库的拆分
    • 逻辑进程的拆分
    • 消息队列
    • 服务发现
    • 负载均衡
    • 战斗服务器
  • 分布式存储
  • 游戏服务器的未来
  • 游戏上云
    • Docker
    • Kubernetes
  • 云游戏
    • 什么是云游戏
    • 云游戏工作原理
    • 云游戏延时

单服务器进程

1978年,英国的一名学生编写了世界上第一个MUD程序《MUD1》,MUD1主要采用文字叙述方式,进入游戏后服务器通过文字告诉你在什么场景,你有什么数据等等交互,比如你输入往上走,程序会告诉你爬到了半山腰,如下图。

MUD

1980年《MUD1》程序接入ARPANET并且程序的源码也共享到了ARPANET,此后《MUD1》出现了众多改编版本,不断完善的《MUD1》也产生了开源的MUDOS。MUDOS采用单线程无阻塞套接字来服务所有玩家,所有玩家的逻辑请求都发到同一个线程去处理,主线程每隔一秒钟更新一次所有对象,玩家数据直接存储到本地磁盘。

多服务器进程

2000左右,网络游戏已经从文字MUD进入了全面图形化年代。游戏内容的越来越丰富,游戏数据量也越来越大,早期MUDOS的架构变得越来越吃不消了,各种负载问题慢慢浮上水面,传统的单服务器结构成为了瓶颈。因此将服务器拆分成多个游戏逻辑服务器(Game),将玩家分摊到各个游戏进程中,每个游戏逻辑服务器负责一定数量玩家的服务,如下图。

多服务器进程

多类型服务器进程

早先参与网络游戏玩家较少,游戏内容也比较简单,所有的游戏内容逻辑都在同一个服务器进程中运行。随着图形化技术的发展,网络游戏玩家越来越多,游戏内容越来越丰富,越来越复杂,导致游戏数据也越来越大,因此出现不同类型的服务器进程来服务不同需求。

数据库的拆分

服务器的一个重要功能是存储玩家的游戏数据,以便下次玩家上线时能读取先前的游戏数据继续游戏。早前文字MUD游戏的数据持久化存储使用的是服务器本地文件存储,玩家下线时或者定时将数据存储在EXT磁盘中,这样的存储在逻辑上是没有问题的,但是玩家频繁的上下线会导致服务器频繁的I/O,导致负载越来越大,以及EXT磁盘分区比较脆弱,稍微停电容易发生数据丢失,因此第一步就是拆分文件存储到数据库(Mysql)去,如下图。

数据库的引入
  • 数据库代理进程(DB)

将数据库拆分出来后,游戏逻辑与数据存储分离,减少了系统的耦合性。如果各个游戏逻辑服务器(Game)需要取数据的话,可以直接连接数据库获取数据,但是当有大量玩家同时操作时,多个游戏服务器同时存取数据库,出现大量数据重复访问和数据交换,使得数据库成为瓶颈。于是在游戏逻辑服务器(Game)和数据库之间增加一个数据代理进程(DB),游戏服务器不在直接访问数据库而是访问数据代理进程,数据代理进程同时提供内存的数据缓存,缓存一些热点数据,减少数据库的I/O。如下图。

数据库代理进程(DB)
  • 内存数据库

互联网技术的开源化,极大的促进了各类专用软件的发展和完善,开源技术出现了一种专用的内存数据库,这类专用内存数据库提供易用方便的存储结构体,而且拥有很高读取性能,因此游戏服务器引进这类专用内存数据库,用于缓存服务器热点数据。目前内存数据库使用比较广泛的是Redis和Memcached。引入内存数据库之后,数据库代理进程(DB)不在缓存数据,而是变为玩家上线时将玩家数据从Mysql数据库中加载到内存数据库中和定时将内存数据库中的数据存储到Mysql数据库中。

内存数据库

逻辑进程的拆分

上面的结构并没有持续太长时间,由于游戏功能类型的逐渐丰富,为了提升游戏各功能运行速度以及游戏体验,开始出现多种专用服务器类型,比如聊天服务器(IM),匹配服务器(Match)和排行榜服务器(Rank)等,将这些专用服务器独立出来有几个好处:

  • 降低耦合性:如果所有逻辑在一个进程中运行,某个游戏功能出现故障的话,将会影响到游戏的所有功能,导致游戏不能继续下去。比如将聊天拆成单独的服务器,聊天服务器挂了的话,只会影响聊天,不会影响你的大厅逻辑、场景逻辑和其他逻辑。
  • 分摊压力:像匹配这种功能通常需要大量的玩家放到一个池子里,然后从中选出几个能力值相近的玩家进行对战,这其中涉及大量的排序和比较运算,会导致CPU占用大,从而阻塞其他逻辑的处理。所以一般都会将匹配这样的功能拆成匹配服务器(Match)。
  • 保证数据一致性:典型的就是组队这种,队伍由多个人组合到一起,每个玩家由于压力的负载可能被分配到不同的逻辑服务器(GameServer)中,如果在各自逻辑服务器中维护一个队伍数据,会存在数据不一致的情况,比较难处理,所以较好的方式是拆分队伍功能成组队服务器(Team),将队伍数据放到一个地方去。

拆分成不同服务器类型后,架构图如下:

逻辑进程的拆分

拆分成各个不同的服务器之后,同一个玩家客户端可能出现与多个服务器同时进行交互,比如你组队时匹配或者匹配时聊天等,而且有些状态频繁变更,比如玩家频繁匹配和取消匹配。如果每个具体功能客户端都要连接一个对应服务器的话,连接的变更和数据的通信会变的非常麻烦,而且中间状态容易出错,所以开始拆分出一个网关服务器(Gateway)。

网关服务器(Gateway)

把客户端和服务器之间的网络功能单独提取出来,让客户端统一去连接网关服务器,客户端发送的数据由网关服务器转发到后端各个类型的游戏服务器。而各个游戏服务器之间的数据交换也统一到网关服务器进行交换。

消息队列

上面类型的服务器基本能稳定的为玩家提供游戏服务,但是扩展性非常的差,每个网关服务器(Gateway)要跟所有类型的所有逻辑服务器维持连接,一些大型游戏这样的逻辑服务都可能有好几千个,如果每个都维护一个连接的话,光维护这些连接就会消耗大量的内存和运算,而且每新增一个逻辑服务器都要跟所有网关服务器连接,扩展性很差。所以服务器之间的通信通常都会增加一个消息队列进程,专门用来服务器之间内部转发消息。

  • 全局服务管理器(Master)

老版的服务器通常会有一类全局服务管理器(Master),全局服务管理器全服只有一个,会存放全服共享或者唯一的数据,早期的数据缓存功能也是由全局服务管理器来实现的,通常全局服务管理器还会存储和管理所有服务器的信息,比如服务器的IP地址、服务器的容量和服务器的增删等,还有就是全局服务管理器(Master)需要与每个服务器进行连接,用心跳维护服务器是否处在可用状态,所以服务器之间的消息转发由它来承担,全局服务管理器(Master)扮演着消息队列的角色。

全局服务管理器
  • 分布式消息队列

一些分区分服的服务器架构,比如分上海服、北京服和杭州服等,一个分服同时在线人数可能不超过几万人,这样服务器架构差不多够用了。现在基本上很多大型游戏也使用这样的结构,但是对于全国同服或者全世界同服的大服务器结构下,这样的架构存在一个严重的单点问题,因为所有服务器间的消息都要通过这个全局服务管理器(Master)转发,这个服务管理器的压力非常大,只要它崩掉的话,那整个游戏都跑不起来,所以会将单点的消息队列换成分布式消息队列,以减轻单个消息队列的压力。现在外界使用比较广泛的分布式消息队列有kafka、rabbitmq和nats,这些都是工业级的消息队列,功能很完善,但游戏界为了性能和自定义化一些功能,通常是自己写分布式消息队列,比如将Master换成分布式Master。

分布式消息队列

消息队列一般使用订阅/发布(sub/pub)模式,每个服务器向消息队列订阅自己要监听的主题(Topic),如果自己有消息发布(pub)的的话,就向消息队列发布,不用管向哪个服务器发布。自己订阅自己需要的,自己发布自己要发送的,很好的解耦了服务器间的耦合。

服务发现

消息队列由单点转换成分布式,消息队列也会从服务管理器中脱离出来,专心做消息转发的功能,那服务管理器中剩下的功能怎么办?剩下的其实就是服务发现的功能:存储各个服务器信息(IP地址,容量,服务器ID,服务器类型等)和管理服务器的增删等功能。

怎么理解服务发现的功能?我举一个实际例子。假设你的游戏已经上线,服务器也正在运行中,到了某个节日,游戏做了一个活动,这个活动做的太好了,吸引了一大批玩家,大量的玩家导致你原有的服务器撑不住,需要在线加服务器,这时候就会出现几个问题:原有的服务器怎么才能知道新加了服务器?新加的服务器怎么知道老服务器信息?服务发现就是要解决这样的问题。

服务发现

新加的服务器A向服务发现中心注册自己的信息,信息注册后,服务发现中心会将服务器A的信息广播给所有老的服务器,通知老服务器有新的服务器加进来,同时也会向新服务器A发送所有老服务器的信息。

服务发现本质上是一类数据库,这类数据库为了保证数据的高可用会支持容错性。容错性一般由数据库备份保证,也就是一份数据会保存在多个机器上,保证了容错性又会带来一个新的问题,那就是多个机器上的数据是否一致,业务逻辑应该用哪个机器上的数据,数据一致性由一类共识性算法解决,比较出名的是paxos算法及其简化版raft算法,这类算法比较复杂,这里不细说,这两类算法的工业级软件实现是zookeeper和etcd。

etcd

负载均衡

什么是负载均衡?为什么要负载均衡?每个服务器由一台计算机组成,单个计算机只有有限计算资源(CPU、内存和网络带宽),当大量玩家都往一个服务器中发送请求时,服务器因为计算不过来,大量请求数据积累超过内存,这样会直接导致计算机崩溃。虽然可以将服务器换成性能更好的服务器,但单个服务器性能受硬件的限制,计算的有限性很低,而且动态扩展性不强,比如线上要临时加计算资源时,不可能直接关服务器吧。所以一般都是通过软件方法,将输入的网络流量分配到多个计算机中,以平摊计算压力,这个软件方法就是负载均衡,总的来说负载均衡是高效的分配输入的网络流量到一组后端服务器。

一个游戏会有多个阶段需要用到负载均衡,这些阶段都有个共同点就是涉及到服务器的选择和变更,比如登录时要选择哪个服务器登录,RPG场景切换时服务器的切换,匹配成功进行战斗时等等,这些阶段都会涉及到负载均衡。负载均衡针对不同需求场景有不同的负载均衡方法,这里主要写登录服(Login)和网关服(Gateway)的负载均衡。

登录服务器的负载均衡

登录服务器是在线游戏的入口,没有登录服的话,你的游戏客户端进不去游戏,卡在登录页面。登录服的负载均衡方法大概可以分为两种,这两种方法与服务器的架构相关联的,第一类是分区分服的负载均衡,第二类是大服务器下的负载均衡方法,大服务器和分区服服务器主要的区别是:大服务器下所有人(全国或者全世界的人)可以一起比赛,不会出现同一个账号有不同数据,而分区分服的服务器是不同的登录服你的角色数据是不同的,比如你在北京服是100级,那你选择杭州服后是1级。分区分服和大服务器架构最本质的区别是是否公用了数据库。

  • 分区分服

这类服务器会显示的让玩家选择在哪个服务器登录,比如在杭州服登录,比较典型的像王者荣耀这种就是使用这种方式,你进入游戏时会推荐几个空闲的服务器给你登录,如果选择已经爆满的服务器登录,会提示你服务器爆满,不能登录,这类负载均衡的方式是由玩家来决定的。

  • 大服务器架构

大服务器架构下所有人都可以在一起比赛,在登录时也不会让你选服,只有一个登陆按钮,典型的像吃鸡这种游戏就是使用这种架构。那一个登录按钮是否意味着只有一个登录服务器?所有人都连一个服务器不会爆炸吗?其实登录服还是有多个的,只不过在登陆时客户端登录时程序会自动的帮你选择在哪个登录服登录,登录进去后,所有人共用同一组后端服务器和同一组数据库,所以全部人可以一起比赛。这类负载均衡方式是由客户端计算哪个服务器,计算的方法有很多,比较简单直接的就是在登录服中随机选择一个。

网关服务器的负载均衡

Login服务器是在线游戏的入口,通常为了更好动态的扩展服务器、减少向外界暴露内部服务器的入口以及承担更多人的登录逻辑,登录服务器所处理的逻辑很少,基本上是账号的验证、角色的创建和角色数据的加载,等账号验证完毕后,登录服根据负载均衡算法给玩家分配一个网关服务器,之后游戏的逻辑消息由网关服务器处理和转发。网关服务器的负载均衡方式通常是最小分配,也就是在一定阈值之上从现有的网关服务器中选择负载最小的一个。

网关服务器的负载均衡

登录成功后,客户端会和登录服务器断开,以减少登录服务器压力以供其他人登录。

战斗服务器

上面的服务器基本上是一个大型房间类游戏服务器的完整结构了,网关服务器用来转发消息,各类内部服务器用来处理各个游戏功能的逻辑。但是所有类型的游戏功能都要经过网关服务器来转发到后端服务器吗?比如游戏的实时战斗功能,像体育竞技,吃鸡,王者荣耀的战斗。如果这类对于实时性要求非常高的战斗功能也经过网关服务器的转发的话,产生的延时是非常高的,你释放一个技能,对面半天才掉血,这非常影响战斗体验。所以一般会有一类战斗服务器(Battle),客户端直接连接战斗服务器(Battle),不用网关服务器的转发。

战斗服务器

分布式存储

由于大型服务器数据量比较大,最终的DB和Redis也会换成分布式数据库。下图是现在房间型游戏服务器主要结构。

分布式存储

游戏服务器的未来

玩家习惯的变迁是个缓慢的过程,因此游戏玩法在短时间内也不会有大的变化,这也会导致游戏逻辑服务器架构也不会发生太大的变化。2003年魔兽无缝大世界出来时,刷新了大家对服务器的认知,但是这类游戏服务器架构出来还是太早了,到现在用无缝大世界的游戏也非常少,个人认为无缝大世界在近期不会有太大的发展。

从服务器历史发展来看,服务器发展趋势主要取决于玩家游戏需求以及上下游技术产业链。游戏内容的越来越精细,互联网传输量的越来越大以及云计算的发展壮大,个人认为未来服务器发展是游戏上云以及云游戏。

游戏上云

先前的游戏服务部署都需要经历两个阶段,一个阶段是服务器硬件的采购以及服务器部署的配置,另一个阶段是服务器的长期运维。服务器采购以及部属配置的整个流程可能需要数个月之久,而且服务部署配置后需要专门的专家进行管理,这些流程对于一些中小型公司来说是很繁杂的,会造成很大的成本问题,这也就催生出了云计算。

云计算是一种基于互联网的计算方式,通过这种方式,共享的软硬件资源和信息可以按需求提供给计算机各种终端和其他设备,使用服务商提供的电脑基建作计算和资源。有了云计算后,公司可以快速购买和配置所需的服务资源,从而花更多的资源在产品本身上。

游戏上云需要两个技术,一个是虚拟化技术。虚拟化技术是一种资源管理技术,是将计算机的各种实体资源,如服务器、网络、内存及存储等,予以抽象、转换后呈现出来,打破实体结构间的不可切割的障碍,使用户可以比原本的组态更好的方式来应用这些资源。这些资源的新虚拟部份是不受现有资源的架设方式,地域或物理组态所限制。另一个是服务编排技术,一个游戏服务的数量可能有成百上千个,而且不同的服务可能分布在不同机器上,这会给服务管理造成很大的困难,所以需要服务编排技术来解决。

Docker

主要是三个部署方式,传统部署、虚拟机部署以及容器部署

  • 传统部署

比较典型的游戏部署方式是服务器运行某个操作系统(如Ubuntu),然后各个游戏服务以进程的方式直接运行在操作系统上,因为每个进程有自己的地址空间,所以服务间的内存空间是隔离的。这种部署方式的优点是简单直接,服务没有额外的一些运算,可以极大化的利用运算资源。但这种部署方式很难限制同一台物理机上每个服务的资源使用(CPU内核的分配),存在资源争夺情况,很可能因为某个服务占用较大的计算资源导致其他应用不能正常服务,而且因为服务在同一个宿主操作系统中,各个服务可以通过读取文件感知到对方的存在,存在很大的安全隐患问题。

  • 虚拟机部署

一台专用服务器的CPU内核数可能有上百个或者上千个,为了更好利用一台服务器的计算资源,避免不合理的竞争,所以引入一种完全虚拟化技术。虚拟化技术允许在物理机上同时运行多个次级操作系统。我之前用的比较多的虚拟软件是VMware,VMware使用Hypervisor对硬件资源进行虚拟化,在使用VMwave的时候需要配置虚拟机的CPU、内存和网络等资源,配好后在虚拟机中安装对应的操作系统和软件。每台虚拟机可以配置自己要使用的资源,各个虚拟机的资源互不干扰,有一个很好的隔离效果,但是虚拟机需要安装完整的操作系统,导致非常笨重。

  • 容器部署

比虚拟机更轻量级的是容器技术,如Docker。容器与虚拟机的主要差别是隔离层不一样,虚拟机在物理层面上进行隔离,然后在之上安装操作系统,容器是直接运行在宿主操作系统上,并不需要在额外安装操作系统。Docker使用Linux隔离技术(CGroup和Namespace)来隔离各个服务,并直接调用操作系统的系统调用接口,从而降低每个容器的系统开销,实现降低容器复杂度、启动快、资源占用小等特征。

虚拟机和容器都使用镜像来存储运行环境。对于Docker来说,应用的源代码与它的依赖都打包在Docker镜像中。一个游戏产品生命周期通常要经过开发团队、测试团队和运维团队。早前没有这样的容器时候,服务的交付和升级都会导致多个团队重复性的安装新的依赖环境,而且一些老上线运营的游戏都不敢轻易升级服务,生怕环境不一致导致服务运行不起来。Docker的出现很好的解决了环境问题,环境一次配置各地运行,这也降低了各个团队的交付成本。

部署

Kubernetes

Docker容器本身适合运行单个服务,但一个游戏的服务有可能上千个或者上万个,这些服务可以分布在不同物理机上。如果只有几个容器,那管理是非常简单的,但当容器有成千上万个的时候,很可能会导致容器管理和编排变得非常困难。对于一些大公司来说,因为要经常维护大型服务器集群,所以都会有自己写的一套集群管理方案,这些方案包含服务资源配置、服务资源使用监控、健康状态检查以及服务的负载均衡等。

  • Kubernetes在游戏界的使用

2014年Google开源了自己的容器编排与管理工具Kubernetes,Kubernetes开始逐步在互联网界扩散,2017年之后大量互联网公司开始应用Kubernetes。但奇怪的是游戏界到现在其实也很少游戏服务使用Kubernetes部署,难道是因为技术原因吗?这个问题其实还有个大学老师专门写了篇论文来探讨( diva-portal.org/smash/g),给出的结论是没有技术原因,只是因为习惯问题。结合自己在游戏界的经验,这个结论是正确的,当然还有一些游戏特性原因,游戏相对于互联网产品的主要差异是游戏对网络延时要求更高,使用Kubernetes的话会因为一些额外配置带来网络延时和处理延时。

之前游戏部署更多的是使用脚本部署,一些Kubernetes主要支持的特性,如服务状态监控和负载均衡功能,其实是游戏服务内部功能就要支持的,并不需要外部工具在单独支持,再加上一些大型游戏公司的产品已经上线很久了,相应的服务部署工具也会不断针对性完善,有了更熟悉的专用部署工具,而且Kubernetes本身是有上手成本的,一堆新概念要学习,所以游戏界应用Kubernetes需要一定的过度时间。当然,现在的一些新游戏都开始使用Kubernetes部署,像网易雷火的各个新游戏也都用Kubernetes部署,使用Kubernetes部署可以更方便接入公有云,动态创建游戏服务,更合理分配服务计算资源。

Kubernetes
  • Kubernetes基本概念

Kubernetes的核心概念是pod,一个pod包含一个或者多个共享存储和网络的容器,以及怎样运行这些容器的规范,pod是Kubernetes上最小的部署单元,其他的一些工作负载是多个pod的扩展组合。一个pod典型包含一个运行游戏服务的容器以及一些额外的监控容器和发送log服务容器。

Kubernetes使用YAML来定义pod如何运行,如pod名字、使用端口以及IP、CPU和内存限制。Kubernetes的整个架构图如下。

Kubernetes基本概念

云游戏

云游戏现在使用越来越广泛,以下会总结什么是云游戏,怎么实现云游戏以及目前云游戏的主要问题点和解决方案。

什么是云游戏

随着云计算的发展,基于云的一种游戏新形态也被提出,那就是云游戏。云游戏是游戏运行逻辑以及画面渲染由远端的服务器来完成,玩家设备不用在下载安装游戏软件,只用从服务器接收音视频流并在设备上播放。因为玩家设备并不用运行游戏,所以玩家可以在任何地方用手机这种低性能的设备玩3A主机游戏。云游戏跟传统游戏运行的最大差别是游戏是否用本地设备的GPU渲染游戏画面。

云游戏

云游戏工作原理

云游戏主要的工作是将服务器的游戏音视频传输到玩家播放设备上,就跟看电视差不多,不过云游戏跟电视的一个主要区别是:云游戏是有交互的,画面需要根据交互来显示,也就是需要实时渲染。大致的实现结构如下,下图也是Google云游戏平台Stadia的工作流程。首先是对服务器游戏的音视频截取并将其编码成流媒体数据,然后使用传输协议将数据传输到玩家设备上,玩家设备将数据解码并将其播放。

云游戏工作原理

画面截取

画面截取的方法很多,不同显示驱动软件或者不同操作系统有不同的画面截取方法,比如GDI 抓图、BitBit、DDA(Desktop Duplication API)、IDD(Indirect Display Driver)、DXGI等等,DXGI是Windows系统中用户模式下最底层的图形设备接口,可以直接获取显示器的内容。

音视频编解码

游戏视频数据根据不同游戏画面刷新频率和分辨率有不同的大小,但通常都是很大,所以在网络上传输时都会使用视频压缩编码,目前使用比较广泛的是H.264编码格式,H264有参考帧的运动补偿、帧内预测等新特性,视频质量更高,码率更低。相较于H.264编码,最新的是H.265编码,H265在架构上与 H264 相似,但H265在图像分块、变换编码、预测编码、熵编码等模块上提出了更优的算法,提高了编码的压缩率、鲁棒性,在相同画质的情况下理论上 H265能比H264节省一半的带宽。H.264已经在手机、平板和浏览器上支持。音频一般使用opus或aac来编码。

数据传输

视频和音频编码后得到一个个数据块,然后将数据块传输到客户端上。Google的Stadia直接使用WebRTC传输音视频数据。当然也可以直接使用原生TCP、UDP和KCP协议传输,对于一些实时性较高的产品,比如强竞技游戏,可以使用KCP传输,KCP传输数据要比TCP要快。相对来说流视频使用UDP传输会更合适,因为游戏画面对准确性要求不高但是对实时性要求高。

画面显示与输入采集

传输过来的数据块解码后得到原始的画面和声音,然后使用SDL呈现画面和声音。云游戏显示质量可以分为分辨率以及帧率。良好的云游戏画质需要高分辨率(至少1080P),实现分辨率的提升需要编解码算法以及硬件能力的提升。游戏的每一帧图片是实时渲染的,每秒显示在显示器上的画面数量,决定了云游戏的体验(至少60FPS)。玩家的操作,比如键盘、鼠标、手柄等外设的信息采集也可以通过SDL实现,收集后将数据传给服务器。

云游戏延时

实现一个能运行的云游戏平台其实不难,现有的技术基本上很容易达到,但为什么现在很少人用云游戏平台玩游戏了?抛开什么商业模式和服务器成本不说,其中的主要原因是云游戏有很大的网络延时,这样的延时很影响游戏体验,尤其是一些对延时比较敏感的实时竞技游戏。2019年网易雷火的一位引擎大佬参加GDC时,现场测试了google Stadia云游戏平台的延时,整个延时大概在200ms左右( zhuanlan.zhihu.com/p/59),云游戏带来的额外延时是70ms左右,从视频上来看延时还是很明显的。据研究表明,游戏延时需要保持在150ms以下才会有一个较好的体验。

对于传统的在线游戏来说,延时是一个常见问题,比如移动延时。移动延时可以通过游戏逻辑来降低,比如影子跟随这类根据轨迹推算的算法。然而,这类算法并不适用于云游戏,因为云游戏仅仅传输游戏画面,没有游戏逻辑状态。那么是什么造成了云游戏的网络延时了?现在又有哪些解决方案了?

延时的主要原因

造成云游戏延时主要原因可以分为三类:

  • 网络延时:玩家操作信息发送到服务器以及客户单接收到服务器音视频流总共时间。
  • 播放延时:玩家设备接收到编码数据后到解码数据并将其显示到屏幕上的延时。
  • 处理延时:服务器接收到玩家命令处理命令并返回相应视频的时间。

网络延时

现在云游戏体验最大的问题是网络延时问题,网络延时的主要原因是网络包在路由器上路由,网络包所经过的路由器越多,那么网络延时也会越大。由于云游戏基于云计算发展,云计算服务器分布在不同地理区域上,所以可以用云计算来选择离玩家最近服务器来降低延时,这类服务器被称为边缘节点(Edge node),所形成的技术就是边缘计算。厂家将游戏部署在边缘节点上,玩家在请求云游戏时,根据每个边缘节点的延时和负载量来选择延时最低的节点进行服务。根据Google Stadia的设计者表述,Stadia有7500个边缘节点部署在合作的ISP厂商中。

边缘计算缩短了服务器到玩家的距离,5G技术解决云游戏传输数据量问题,5G提供10Gbps以上的峰值速率、更佳的移动性能、毫秒级时延和超高密度连接。这样的技术很好的满足了云游戏的低延时和高带宽的需求,因此5G技术的普及也会促进云游戏的进一步发展。

播放延时

播放延时主要取决于视频编解码以及视频压缩技术,目前使用广泛的是H.264格式,像Stadia也是支持这个的。对于移动云游戏来说H.264还是不够,主要的原因是,移动设备需要在严格的延迟要求下传输大量的数据,包括高质量和高帧率的图形,这就会要求移动设备需要由一个更高的带宽。

除了视频压缩技术之外,Stadia为了降低延时提出负延时(Negative Latency)技术,这个技术使用马尔科夫链预测玩家在未来几帧内的输入,并且渲染对应的画面返回给客户端,如果在错判时给出补偿(快速隐藏错误的渲染)并且调整输入渲染。负延时技术对一些单机游戏来说比较友好,但是对于一些网络游戏来说比较难应用,因为游戏变量不仅仅只有当前玩家的输入。

处理延时

渲染一个游戏画面来说,肯定选择最好的GPU来渲染,产生的延时也低。但是考虑到成本,不可能任何游戏都使用最好的GPU来渲染,比如一些对渲染要求低的2D游戏。现在云游戏厂商的持续亏本很大一部分成本来自于硬件配置的不合理使用,所以在保证游戏体验的前提下,合理的调度服务器的硬件配置可以降低成本,增加企业的营收。

虚拟化在整合游戏资源和降低硬件成本方面起着至关重要的作用。目前为止,CPU,网络接口和数据存储虚拟化技术已经发展很成熟了,典型的像Docker容器技术。但是GPU却是个例外,先前,研究人员针对虚拟机提出了一种新的GPU算法“vGPU“,“vGPU”的基本思想是将GPU计算资源分割成多个块,并在图形处理中引入CPU,以弥补GPU计算资源的损失。

GPU虚拟化可以增加服务器的游戏并发能力,增强虚拟机的计算能力。GPU虚拟化的问题是阻碍云游戏实现令人满意的延迟和响应时间的最大障碍之一。

网易云游戏

Google在2019年的GDC大会上正式发布云游戏平台Stadia,同年的11月份网易云游戏平台也推出。目前在杭州使用手机玩网易云游戏平台中的光遇,网络延时可以控制在50ms以内,网络延时并不明显,游戏体验也蛮好的。

总结

随着云技术的发展,相应的游戏形式也发生了变化,产生了云游戏。云游戏因为不用下载游戏,不限设备等特性,不断发展壮大,但由于云游戏的延时和画面质量问题,云游戏也面临着挑战。

参考

  • iopscience.iop.org/arti
  • arxiv.org/pdf/2009.0978
  • youtube.com/watch?
  • en.wikipedia.org/wiki/C gaming%2C sometimes called gaming,game remotely from a cloud.
  • gdcvault.com/play/10270
  • gdcvault.com/play/10265
  • stadia.google.com/
  • gameres.com/889974.html
  • docs.kubernetes.org.cn/
  • draveness.me/kuberentes
  • zhuanlan.zhihu.com/p/59
  • diva-portal.org/smash/g
  • skywind.me/blog/archive
  • en.wikipedia.org/wiki/H
  • github.com/ksyun-kenc/l
  • www-file.huawei.com/-/m
发布于 2022-04-18 22:26

1)逻辑复杂,其实这是最大的特点。

2)长连接为主,(虽然有的用UDP做帧同步,其实逻辑还是长连接模式),同时在线决定了这点。

3)REQ-RSP交互模式为主

4)缓冲(前端,服务器,DB都有缓冲)

5)上面几点决定了一般有状态

6)状态同步+帧同步,(帧同步算半个异类)

7)还是三层结构为主。(这是一样的地方)

8)安全+反外挂

9)喜欢单线程

10)对网络要求略高(网速和流量)

11)还算追求性能

就这些吧。其实本质没啥区别。有点特点而已。

编辑于 2021-07-20 01:13

游戏服务器的出现同游戏本身的需求息息相关,也让它具备了其他服务器不一定具备的特点。这里从游戏服务器的起源、功能特点、分类和发展历史,以及系统架构、开发核心技术和难点、设计原理等方面来介绍游戏服务器技术。

答者:John(腾讯互动娱乐 工程师)


#01游戏服务器概述

概念及起源

普通的服务器主要是作为硬件承载内容,游戏服务器,是服务器硬件和软件的结合。其中,硬件负责承载游戏服务,软件则提供游戏服务。游戏服务器的出现,是因为玩家对游戏有三个方面的需求。

第一,是游戏性的需求。

最早的游戏机,更讲究单局游戏的体验和过程,不可以存储进度。这种单局过关的游戏性,来自于用户体验的提升,来自于玩家对技能、关卡熟悉程度。随着用户体验时间的增长,这类游戏对玩家来说会变得容易,游戏性就会被消耗掉。

随后出现了一些可存档的游戏。比如,红白机上有了最早的可存盘游戏——《三国志:霸王大陆》。网络刚开始兴起的时代,PC端的游戏也是可以存储一些进度的。但当时的网吧基于安全需求,在玩家使用电脑后重置机器,游戏内容就会被清空。从游戏性的需求来看,玩家希望换电脑也能够继续游戏进度。为了解决这个问题,设计者就需要把玩家的数据和剧情放到网络服务上。

第二,是多人联机的需求。

单机游戏有它的乐趣,但更多时候,玩家与玩家之间的互动可以产生更多变化。比如,斗地主这个传统游戏,一共只有52张牌,三个人玩却可以有无数种玩法。为了实现这个需求,一般可以用中转的电脑来转发用户的数据和状态操作。这个操作不局限于用服务器来实现,在局域网上,一些互相转发的方式也同样可以实现。

第三,是保证游戏公平性的需求。

通常,游戏防止玩家作弊的方式就是引入第三方电脑裁判。

上述三个需求驱动了游戏服务器的诞生,它们同样也是游戏服务器的主要功能。此外,游戏服务器还有一个重要功能——充值。

功能

游戏服务器的功能,主要有四个。

(1)包括终端网络连接的建立和会话维护在内的网络服务。

有了终端和前端间的网络连接,才能实现前端后端的交互。而会话维护,主要指用户的登录和登出,同时也是该用户在服务器上的一个生命周期。会话维护还包括断线重连,这一问题在PC端不太容易出现,但在手游端会经常发生网络的切换(WIFI和WIFI、4G基站之间),这些都会导致玩家网络掉线。会话维护使得网络掉线后,玩家在服务器上的生命周期也不会消失。

(2)用户数据的存取

数据读取,一般会发生在以下两个场景:一是登录。玩家登入服务器后,服务器会从存储读取。二是切换。比如,从大厅服务器切换到战斗服务器,也有可能从DB(database,或者文件系统)读取用户数据。

而一般的服务器技术采用三种存储方式:

① 用户下线存取。用户下线时,服务器会对数据进行回写。

② 定时回写。比如,每隔半分钟、每隔五分钟,把数据回写一次。

③ 重要数据立即回写。比如游戏里,玩家打了一个特别贵重、极其稀有的装备,或者涉及金钱交易的数据,都是会及时回写。这种方式是为了解决前两种存储方式可能导致的问题:如果异常掉电,那么服务器会出现异常,导致用户数据丢失。

(3)游戏的逻辑计算。

采用服务器技术后,一些以前单机上实现的前端计算,被放到了后端。这也是为了防止作弊,以及解决以前存在的一些问题。比如,在FPS(第一人称射击游戏)中,玩家是否命中的判断是在前端,但命中后产生的伤害,包括护甲、免伤等数据,都要通过逻辑计算。以前的逻辑计算都是在客户端进行,不可避免地会有作弊的可能。如今,逻辑计算都在服务器进行,减少了作弊的可能性。

(4)是用户行为或状态变化的同步。

在网络游戏中,玩家在用户端的视野范围内,可以看到其他玩家或怪物、NPC(非玩家角色)的动作行为。这种真实世界的模拟,就需要各角色行为和状态的同步变化,这就是后端服务器的功能之一。

特点

游戏服务器虽然是互联网服务的一种,但相对互联网服务有一些自己的特点:

第一是,延迟敏感。延迟指玩家操作动作、发出指令,和动作在画面上呈现图像反馈到视觉,之间有一定的时间差。

第二是,实时的高强度交互。单次请求会产生很多服务器的逻辑,还有一些广播和同步。服务器承受的最大压力的逻辑是移动同步。比如,假设玩家在一个20人左右的场景里,每移动一步,客户端1s之内大概会发出5个移动包(假设),表示玩家方向或移动目标点的改变。对于其他用户来说,服务器也要实时同步,相当于消息量会放大20倍。这对服务器来说,是很高强度的交互。

第三是,业务逻辑复杂,内部耦合度高。由于游戏服务器具有延迟敏感和交互高强度的特点,这决定了服务器的状态维护是一个必然的过程,也导致了逻辑的复杂性。举例来讲,玩家击杀一个怪物,在服务器端,逻辑不仅仅是击杀一个怪物,也可能会触发一个任务,比如玩家今天要击杀15个怪物,这样类似的逻辑。

第四是,变更频度高、幅度大。手游时代,游戏的更新频率非常快,内容非常多。因此,服务器的更新和灰度部署要求会更高。

#02游戏服务器的发展

网络游戏发展史

上世纪七十年代末,网络游戏最早是文字MUD和UNIX网络同步出现。

之后,八十年代末到九十年代初,局域网连接的游戏出现,最早是《沙丘》,其次是《红警》、《魔兽2》和《DOOM》。

到九十年代末,出现了Diablo(《暗黑破坏神》)战网。

1997年,金山发布了一款比较有名的RPG类(角色扮演)游戏《剑侠情缘》。当时,《剑侠情缘》还是单机版的。后来在2003、2005和2009年,分别发布了网络版的1代、2代和3代。

1998年,主打休闲游戏的联众游戏成立。

2000年左右,MMOG(大型多人在线游戏)《传奇》登陆中国。

2004年,《魔兽世界》(WOW)出现。

2006-2010年,手游兴起。莉莉丝游戏做出了一个比较成功的手游产品——《刀塔传奇》。

2010至今,就是休闲类的《纪念碑谷》、网易次元文化的《阴阳师》,再到如今大热的MOBA类(多人在线战术竞技游戏)的对战手游《王者荣耀》。

游戏服务器的发展

第一代游戏服务器,是比较简单的单进程、单线程模型,无阻塞。服务器在接收到玩家的消息后,把消息按照队列进行异步的序列化。

这种单线程的服务器模型,最早的是类似于78年的MUD游戏。使用终端模拟程序telnet等,就可以直接登录。进入场景之后主要采用文字叙述的方式,即服务器告诉玩家在什么场景、有什么数据,然后玩家输入指令。早期的服务器,虽然没有很强的逻辑,但因为整体构架比较简单,所以承载能力较低。

第二代游戏服务器,为了增加并发,在服务器端也发展了多线程和多进程的模型。在服务器本身的逻辑上,开始增加了分区分服的结构。

比较典型的游戏是上图中,EA(美国艺电公司)旗下公司在1997年发布的《Ultima Online》,即《创世纪》。它是世界上第一款图形界面的大型多人在线角色扮演游戏。

此外,还有联众在2000年推出的休闲棋牌游戏。当时,联众跟地方的运营商(电信、联通等)合作,搭建游戏服务器。所以在游戏中,会有南方电信1、北方联通1等分区。这体现了第二代游戏服务器架构典型的分区分服特点。

第三代游戏服务器,相对更百花齐放一些,主要有四种类型。

第一种类型,是在第二代的基础上发展而来,实现三层架构的游戏服务器。

首先,Gate server作为所有玩家的游戏连接,主要负责处理网络的IO部分。然后,通过内部的网络即IDC(互联网数据中心)专网,与游戏逻辑服务器相交互。最后,通过mysql或其他数据库,把用户数据存储到DB server。它的主要特点是,把网络和存储IO进行逻辑分离,可以对每一层进行扩展。一般负载的瓶颈大都在GameServer层,这层可以做更多的扩展,从而支持单区单服增加承载的能力。

2003年的QQGame,是比较典型的三层架构服务器代表。它当时是腾讯首款自研的游戏产品,最高达到过PC端八百多万人在线的成绩。QQGame很快就超越了联众,即使在现在的休闲棋牌市场上,也处于绝对领先的地位。

第二种类型,是服务器集群,上图是比较简单的示意图。

首先,也有与玩家连接的接入类服务器,这里命名为GATE,它负责处理专网连接,在游戏WORLD处理游戏逻辑。然后它会把通用逻辑和功能抽取分离开来,比如管理、聊天、交易以及一些组队和工会,放到独立的地方,再通过Cluster服务器集群的方式提供服务。采用这种分组以后,以前同步的逻辑直接本地调用一个函数,来处理组队和工会,会变到另外一个服务器上,中间就多了一些异步交互。异步交互存在状态维护的困难,所以这种结构开发难度会更高。

MMO和RPG大都是这种结构。其中,比较有代表性的是最早期的《传奇》。它是一个经典的MMO,是盛大引进代理的韩国游戏。

《QQ幻想》和《QQ华夏》,也采用了这种结构。《QQ幻想》是腾讯在2005年,自研的一款Q版卡通类RPG,最高的时候有六十万左右玩家在线。《QQ华夏》则是07年深圳网域公司开发的RPG游戏,当时腾讯做代理运营。

第三种类型,是无缝地图。它的特点主要有三:

① 一个场景服务器只负责一部分场景;

② 玩家进入游戏后,没有加载地图的过程;

③ 在场景边缘处,数据可能同时存在于多个场景服务器中。此时会由world级的服务器进行管理,决定哪个服务器做决策。在边界切换时,不同场景服务器共同持有玩家的数据,玩家就不会感觉到明显的切换。最典型的,就是《魔兽世界》对无缝地图技术的应用。

第四种,是房间型服务器。

图中间的部分是大厅接入群,类似于上文中的gate和游戏服务器。这部分主要负责用户的接入、主要的逻辑处理以及其他一些大厅服务,比如《王者荣耀》和《英雄联盟》的5v5匹配。当很多玩家同时申请进入游戏时,房间型服务器会根据规则挑选出等级接近的玩家,分别组成队伍。之后单局的过程,叫做战斗接入群或房间服务。战斗接入群会做一个分布,比如,根据北方的联通和南方的电信,对用户做就近的接入。再如PUBG mobile,它的大厅集群放在北美,同时在北美、亚洲和欧洲都有战斗接入群,方便各地用户接入。

房间型服务器的游戏比较多,包括《英雄联盟》、《王者荣耀》和《刺激战场》(《和平精英》)等。

#03核心问题、技术和实现难点

核心问题

游戏服务器要解决的核心问题,是满足海量游戏用户稳定和高质量的服务需求。

首先,“海量”指的是,十万到千万级的PCU(Peak Concurrent User,即最高同时在线用户)。此外,还有个名词DAU(Daily Active User,日活跃用户),是游戏运营的数据指标,而PCU主要考量服务器的性能数据。

其次,“稳定”代表着:

①服务器不能宕机,一旦服务器出现问题,用户的直观感受就是掉线了。

②要容忍弱网络的问题。比如,用户网络不稳定,连接断掉之后,服务器可以允许用户在短时间内进行WiFi和4G的切换,允许用户重新连接,保证服务可以继续。

最后,“高质量”主要是指处理网络的延迟和一些逻辑问题。

核心技术和实现难点

游戏服务器的核心技术和实现难点主要有四个:

① 单服处理能力

对于不同类型的游戏,单服即一个服务器,支撑的在线玩家数量是不同的。休闲类如棋牌游戏,可以支撑两万到三万的玩家;MMO可支撑的玩家数在五千到八千;而射击类等高强度交互的游戏,只能支撑两千到三千的玩家。

② 逻辑耦合度高

服务器有很多集群的设计,所以在单服处理能力方面,会有算法的优化。比如,排序方面有排序查找、hash(哈希,“散列”算法)和二叉树;还有用空间换时间的方法,把经常用的数据放到内存里,减少CPU的经常读取。

服务器设计比较难的地方在于逻辑设计。很多逻辑是一个整体,要想将它分离开,就要找联系相对薄弱的地方。举例来说,组队和游戏逻辑的相关性比较小,就可以抽离出来。有些服务器单独将组队剥离,那么组队的消息接口和逻辑,就容易抽离成另外一个独立的服务器。但即使逻辑之间可以分解,这也是有限度的。分解的越细,异步协作和状态维护的内容就会越复杂,游戏开发的难度就越大。

③ 延迟敏感

在防止延迟上,前端和后端需要一定配合。比如,前端会提前按帧缓存,当出现网络延迟和卡顿时,游戏其实还可以继续进行一段时间,这样玩家对延迟就没那么敏感。但是,提前缓存会存在玩家手感差异的问题,而且也不能缓存太多,否则玩家感受到的延迟就会比较明显。

④ 版本更新

现在,手游时代很少会停机更新,即使有也大都在凌晨。更流行的方式是不停机更新,这就要求逻辑、资源一定要做程序设计上的分离,保证在更新资源时,程序可以重新读取并加载,且不中断。

上图是游戏服务器的一个系统结构示例,它偏向于房间型结构。首先,前端采用TCP或其他协议进行接入;之后,大厅接入群,主要包括接入服务器和游戏逻辑服务器,通过Proxy或者哈希算法的方式,把DB(database,数据库)做分布式存储。因为一台DB存储不了千万上亿级的用户数据。最右侧,是一些内部的接口。举例来讲,如果运营商要发布活动如经验加倍、金币加倍等,就会通过管理端向游戏逻辑服务器做接口服务。图中的战斗接入群,主要处理单局的游戏内容。

此外,在公共平台还有支付、关系链和排行榜等功能。支付与游戏逻辑的相关性不大,可以独立出来。支付的大致方式有两种:一是将人民币转换为游戏内代币,二是代币旳消耗。关系链一般是第三方平台的关系链服务,包括QQ关系链、微信关系链和Facebook关系链等等,有些服务通过第三方的API或接口进行同步。排行榜也可以做成一个独立公有的服务器。

游戏服务器的网络协议主要有Tcp、Udp、R-udp和http四种。

Tcp是面向一个流的模型,本身有滑动窗口重传的机制。协议没有边界,但有流量控制,丢包会影响它的传输速度。

Udp是点对点的,没有可靠性的控制,不能保证消息包一定被收到,丢包会影响传输的成功率。

R-udp是在Udp的基础上,吸收了Tcp的特点,保证了可靠重传的机制。

http一般用于拉关系链或web端发布接口到游戏侧做活动的场景。

上图介绍了游戏的接入逻辑。手游玩家在开启游戏时,登录后的第一个界面就是选区,所有区的列表,都放在目录服里。目录服的实现方式有两种,一是将目录服都放到客户端,二是目录服放在单独的服务器上。若采用方式一,当选区增加时,客户端就需要更新。所以,大部分的目录服都放在单独的服务器上,列出有哪些区,这样即使选区增加客户端也无需更新。

一般来说,各个逻辑服务器会向目录服上报各自的服务状态。当用户登录时,目录服首先就会回复一个服务器列表,客户端可以看到游戏的各个选区,如一区、二区等。在这个过程中,目录服会尝试各个服务器连接的响应速度,最后选择一个最近的登录服,登录到大厅。

在地图服务器的技术中,视野同步最常用的是九宫格技术。九宫格中的一块格子,比屏幕略大。服务器一般会认为,以玩家所处格子为九宫格的中心,整个九宫格的其他玩家和怪物都是玩家关注的对象。当玩家在格子内移动时,玩家的视野不会发生变化。但如果玩家移到其他格子中去,视野就会发生变化。比如图中的例子,若用户由B3移动到C2,则视野范围会由紫色九宫格变为黄色。由于视野范围变化不是很大,服务器不用立即加载玩家的同步数据,除C2之外,其他格子中的任何行为都不会同步给玩家。九宫格技术保证了用户在行走中的平滑感的同时减少了交互的次数。

地图管理,包括动态阻挡和静态阻挡。动态阻挡,指两个玩家同时到达一个地点,服务器是否能找到平衡点来同时显示两个玩家的位置。静态阻挡则指,静态的物件放在某处,服务器要判断玩家是否能走过去。比如遇到一堵玩家走不过去的墙,那这堵墙就是静态阻挡。

移动同步,主要需要解决的问题是网络延迟导致的拉扯和平滑。平滑主要是利用数学上的插值技术,将两个差异的地方在几帧之内快速平滑地拉过去。

游戏中的商品购买服务,可以看作是一个异步状态机。当客户端的用户提出购买请求后,购买服务器提出预扣费请求,将信号传递到货币系统服务器中,同时添加物品记录到DB服务器。在记录添加后,再次返回货币系统服务器进行扣费确认,并返回到客户端,完成整个购买扣费流程。这样的异步预扣费机制,是为了防止中间环节出现故障后,导致扣费未发放商品或商品已发放但未扣费的问题。

在DB层的数据存储,一般采用分布式技术。现在的游戏基本都有上千万到亿级的注册用户,庞大的数据量决定了一台服务器不可能存储完全。数据通过关键值key值,传输到路由表中,进而传递给DB层。key值一般是内部生成的用户ID,采用哈希值的方式把数据散列开。

举例来说,有十台DB,100号玩家,那么玩家号除以100,得到的尾数是几就放在第几位,从而把数据散列开。采用哈希值的方式,还有一个固定规律,即存写时都是相同的规则。

路由表有两种方式,一种是直接存在数据发起端,另一种是放在独立的proxy服务器上。

游戏服务进程的框架,和大部分服务器是类似的。都是初始化、退出以及中间的循环处理。循环处理包括网络事件、定时器处理、网络消息处理、事务处理和消息队列处理。网络事件指连接和断连;定时器处理,是通过定时器的计时,来定时保存用户的数据和一些定时逻辑;网络消息处理,是网络上的收发包;事务处理,是服务器产生一个逻辑的时候保存的一些中间状态;消息队列处理,则是在其他逻辑模块发送业务请求时产生的。

中国的外挂问题,相对外国更加明显一点。而韩国的政府对于游戏产业的支持态度,使得防范外挂相对容易,所以很多韩国游戏引进到国内后,就面临着水土不服的外挂问题。外挂,包括键盘鼠标模拟、注入、协议破解和程序破解等方式,还有最难的完全模拟客户端的方式。

反外挂的核心,以服务器逻辑为主。当逻辑放在服务器上时,外挂没有机会。不过这种方式的成本也很高,其一是因为这个逻辑会加重服务器的负担;其二是,逻辑放在服务器上,反馈到客户端时,会导致游戏体验的延迟,影响玩家的游戏体验。常见的反外挂手段,包括动态协议栈、验证码检查、加壳、动态特征码检查进程和法律等方式。

#04设计原理和方法论简述

设计原则

设计原则最首要的是KISS原则,即Keep It Simple,Stupid。系统的设计要尽量简单清晰,不要太复杂,减少模块的耦合,要做到让玩家一看就懂。

其次,是灰度方面的设计。

第一,要柔性可用。柔性可用主要指,当服务器条件有限不能提供完整服务的时候,可以用柔性的方式提供相对优质的服务。比如战斗服务器出现故障时,不能打PVP(Player VS Player,玩家对战玩家),那么要能够打PVE(Player VS Environment,玩家对战环境)。

第二,是在不同场景下提供不同的服务。服务器要保证系统的核心服务是一定可用的。而非核心的服务,如排行榜就可以暂时停止,不能因为非核心服务,而阻塞整个游戏的服务进程。

第三,服务降级和灰度分布。当一些服务出现有损的情况时,可以做服务降级。排队就是服务降级的一种。当玩家人数超过服务器的承载能力时,服务器就可以通知后面的玩家服务器繁忙,来进行用户的排队。

可行技术及工具

已验证可行的常见具体技术,包括:

①无锁通信队列。两个进程在后台线程通信的时候,队列如果只有一端读、一端写,那么是可以不用锁来实现的。该技术最早应用于Linux底层,现在已经比较常见了。

②异步模型。异步模型在服务器技术上应用的比较多。大部分服务器采用Cluster技术时,都会采用服务器协作的方式,那么很多的同步调用就会变成异步的交互。

③通用框架。通用框架包括big world框架和网易大神——云风开发的skynet,这两个框架都比较成熟。skynet的特点,是使用lua(一种脚本语言)。

④Key-value数据库产品或内存数据库。以前的服务器数据库,用的是Mysql等传统关系型数据库。现在主流使用的是Key-value数据库产品,如Redis(Remote Dictionary Server,远程字典服务)和MongoDB(基于分布式文件存储的数据库)等。Key-value数据库大部分是根据一个用户ID,就可以得到用户所有的数据。

关于工具,首先是调试器。Linux下,著名的gdb调试器计算机开发一般都会用到。Windows下,一般使用Visual Studio自带的调试工具。

关于内存泄露的检查,Linux下常用的有valgrind,Windows环境下,则有Leaks Detector。

上图展示了一些性能分析工具。在Linux环境下,一般使用gprof,具体用法可以参考网址 sourceware.org/binutils 。Windows环境下,使用visual studio自带的profiling。此外,还有第三方的工具,如Truetime。

网络抓包工具,是在网络开发中用得比较多的工具。Linux下,最常使用的是Tcpdump。Windows下最常用的是wireshark,它的优点在于,可以直接与网卡进行数据报文交换,同时具有语法过滤功能。

此外,关于静态代码检查,最常见的工具是PC-Lint。

发展现状及前景展望

游戏服务器相对于之前已经发展了许多,而且计算机的综合能力也越来越强。

首先,游戏服务器已进入多核时代。目前正在使用中的PC服务器,最多有六十四核,加上超线程,总共能达到128个核心。

其次,编程语言发展比较快。在C语言之后,Java也有很大市场,用Go的人也多了起来。欧美的游戏,很多用Java做服务器开发。此外,《和平精英》服务器用的是C和lua结合,lua为主写逻辑。lua的性能虽然稍微差一点,但有最大的优点:热加载更新快,开发效率高。

然后,有更真实的游戏世界。游戏的真实性,更偏向于前端设计。虚幻和CryEngine这两个大型引擎,使得游戏对于真实世界的模拟变得非常强劲。不过,这两种引擎都比较重,而Unity引擎是比较轻量的。

最后,游戏服务器会具有更实时的交互和更快的响应速度,做到所见即所得。

好的游戏体验,离不开服务器的开发设计,随着科技和游戏设计的相互促进。互发展,用户将会获得更加优质的体验。

发布于 2022-04-02 10:30

web服务器基本是无状态的.

游戏服务器是强状态的, 耦合自己不说, 还要耦合别人, 别的大区...

发布于 2015-10-05 09:27

游戏服务器跟聊天服务器类似,服务器推(Server Push)是一个必不可少的常用操作.

而普通的网站服务器并不需要服务器推,也就是不需要广播操作,基本都是HTTP请求/响应操作.

游戏服务器相比聊天服务器,操作更多,状态更多.

在一个游戏房间里,聊天,发发信号只是其中的一个小功能.

战斗逻辑,英雄等各种对象在游戏房间里玩家之间的状态同步,都是聊天服务器所没有的.


游戏服务器:CPU密集(Redis:内存状态值读写),网络IO密集(广播).

网站服务器:状态比较少(Redis:会话信息),数据库IO密集.

编辑于 2017-11-04 10:53

战斗服务器核心是主循环战斗逻辑模拟

web服务器核心是数据请求应答响应

一个是计算密集一个是io密集

发布于 2022-04-23 20:36

游戏服务器的大多数系统功能其实也是能用普通web服务器的架构实现的,抛开这个不谈。


核心区别在于 游戏玩法往往需要实时有状态服务,而传统的web服务器架构是无状态服务,几乎不可能满足延迟和性能要求。具体来说:

  1. 实时性。一些游戏类型比如mmorpg,moba对 实时性要求很高,典型的无状态web服务器方案难以满足要求。
  2. 请求频率高。一个万人同服的mmorpg服务器,一天就有几千万上亿个请求,同时有大量的广播,游戏状态数据多,传统游戏服务器方案一台高配物理机搞定。普通web服务器的方案需要较多资源。
  3. 游戏逻辑的耦合性比强。
发布于 2021-04-20 14:44

前面分服的游戏服务器已经说得非常好了。

具体来说,硬件举个例子吧:

Tranquility Tech III - EVE Community

这个链接描述了EVE服务器的整体架构和硬件设备。

发布于 2017-08-10 12:01

这题我会的!!游戏服务器与普通服务器区别有3个方面:

1、技术区别:WEB服务器基本是基于HTTP协议。因为它无需去与浏览器进行主动推送,只需要响应浏览器的访问就足够了。

而在游戏服务器,这样的连接方式肯定是不够用的。很多时候游戏服务器是需要主动推送消息,如系统广播。

2. 思维区别: WEB服务器无需高频即时通讯,对响应速度要求不高。而游戏服务器,大多是需要很及时的响应速度(暂不讨论弱联网游戏)。如DOTA,这种竞技类型的游戏,1秒就能发生很多事。

因此,WEB服务器应该考虑是的多平台的兼容,大量用户访问的高并发。而游戏服务器应该考虑的是高频通讯,高并发。

3. 架构区别:在架构上面,一般访问量不是很大的网站是只有一台服务器的,访问量高的才会进行分布式设计或者集群设计。而大部分游戏服务器都是需要分布式设计的。

游戏服务器与普通服务器都是物理服务器,不过随着云计算技术早已成熟,上云成为一种趋势。尤其是像GPU云服务器,在计算能力、游戏渲染方面做的非常出色。

IDC物理服务器和云服务器区别 (点击放大)

就GPU海量计算而言,阿里云是国内首选。阿里云的GPU云服务器是基于GPU应用的计算服务,最适合AI深度学习、视频处理、科学计算、图形可视化等应用场景。

阿里云的GPU服务器支持周、月、年购买,支持批量支付,对于短期需求的用户来说相当方便。阿里云官方GPU云服务器,官网活动参考:

关于阿里云GPU云服务器选择请以官方文档为准: GPU云服务器官方详解 - 阿里云

当然除了阿里云GPU服务器以外,如果觉得阿里云GPU价格成本高了,追求低成本,可选择c5,g5,c6系列服务器,低至0.26折,计算性能不错还可领取代金券,官网活动参考:

除了阿里云之外,还有腾讯云的GPU服务器,腾讯云的GPU服务器分为渲染性和计算性两种,分别满足不同场景的使用需求;腾讯云目前所采用的GPU 虚拟化技术主要为 PCIE 硬件虚拟化(SRIOV)或 直通(DirectPass-Through)。不过腾讯云GPU服务器相比阿里云

腾讯云的GPU服务器也支持月付、年付、按量计费等多种支付方式。腾讯云官方GPU云服务器:

关于腾讯云GPU云服务器选择请以官方文档为准:: GPU云服务器官方详解 - 腾讯云

华为云GPU加速型云服务器包括G系列和P系列两类。其中:

  • G系列:图形加速型弹性云服务器,适合于3D动画渲染、CAD等。
  • P系列:计算加速型或推理加速型弹性云服务器,适合于深度学习、科学计算、CAE等。

官网活动支持领取代金券,先领券再选择云服务器,是一般流程,官网活动参考:

当然除了上面做游戏的专业云服务器外,如果是搭建小型游戏,选择普通云服务器,轻量应用服务器完全够用了。

编辑于 2022-03-29 22:04