游戏服务端:游戏服务端架构简析

文档主要记录一些流行的服务端架构,并以FPS游戏架构为例,谈谈一些游戏服务端开发可能遇到的问题

常用游戏服务端架构

http服务端架构

  • 对于如棋牌类等交互逻辑较为简单的游戏,一般采用http通信模式,和互联网产品的web服务器架构类似,通过网关将流量分发到各个业务server,进而影响到各类缓存和数据库信息


    对于MMO、FPS等类型的游戏而言,玩家在游戏中是有状态的,双端需要实时交互,对于消息频率、速率都有更高要求,因此需要用到长连接。比较典型的长连接架构如下

分区分服模型

  • 分服模型特征是每个服务器的帐号是独立的,一个服就是一个世界。服务器的承载量达到上限的时候,游戏开发者就通过架设更多的服务器来解决。运营人员根据每个服务器承载的用户量,决定合服、开新服。

  • 对于每台服务器,所有请求会统一经过线程池,通过消息的方式积压在待处理队列中,主线程以轮询的方式处理所有请求。

  • 随着业务逻辑越来越复杂,主线程可进一步拆分成多线程、多进程的方式,部分负责处理逻辑业务,部分处理数据读写等内容。

三层架构模型

  • 在分区分服模型下,同一服务器能承载的玩家数量较少,为了提高玩家之间的互动性,需要对服务器进一步拆分,使得更多的玩家能在同一个游戏世界里互动。
  • 三层架构将网关部分拆为单独的gate服务器,数据存储拆为DB服务器,业务逻辑用多服务器来承载。不同用户在不同的业务服务器上游玩,但数据互通,也可在各个业务服务器间切换。

微服务模型

  • 参考微服务设计思路,可基于三层架构对业务服务器进一步拆分,使得各个服务器处理的业务更专精。拆分后的集群可分为三类:支持水平扩展的有状态服务、支持水平扩展的无状态服务、不支持水平扩展的单点服务

  • 有状态服务(gameServer):用于处理玩家业务逻辑,如战斗、游戏进行任务等内容。玩家战斗、任务等相关数据会计算在这些服务中,一个玩家只会存在于一个server中,如遇进程退出等异常,则可能丢失部分没来得及保存到数据库的数据。对于有状态服务,可以根据客户端流量压力扩缩容。
  • 无状态服务(nogameServer):用于一些计算类的无数据存储需求的服务,例如榜单服务,定期从数据库读,整理成排行榜供玩家查询。
  • 单点服务(singleServer):指游戏中那些有强一致性要求、不具备扩展能力或扩展工作量过大的服务,例如数据库、各类管理器等。此类服务是性能瓶颈,出现异常会导致整个游戏不可用。一般需要通过各类手段来缓解,如数据库加入读缓存,分布式读数据等。

无缝世界模型

  • 在微服务架构中,玩家的游戏场景对应有状态服务的多个server,从一个场景切换到另一个场景意味着server进程的切换,因此对应一定的loading时间。

  • 对于开放大世界网游,loading界面无疑会削弱游戏代入感,因此引入无缝世界模型来解决。

  • 无缝世界一个连续的虚拟世界场景被分成左右两块,分别在不同的Cell Server运行,中间区域的逻辑由两个cell共享。玩家B处在中间区域时,可以同时与两端的A、C进行交互,当B离开共享区域时,数据从离开的server上删除。共享区域的大小可根据游戏规则定义

FPS游戏服务端

FPS游戏如和平精英等,一个明显特征是存在一个大厅功能,所有玩家需要经过匹配排队后才能加入一场游戏,同时游戏进行时与其他服务端模块的数据交互需求较少。

架构示例

一个比较典型的FPS游戏服务端架构,可将服务端模块大致拆解为战斗和非战斗模块,其中非战斗模块可以细分为大厅服务、无状态服务、消息队列、匹配服务、数据库等

下图参考自Amazon GameTech FPS/MOBA 云服务架构

  • 大厅服务(lobbyServer):用户通过网关接入后,会首先进入大厅服务,在这里可以选择进行下一步操作
  • 非状态服务(noGameServer):当用户打开商城、搜索好友、聊天等操作时,就是在和非状态服务模块进行交互。考虑到这类操作一般实时性不高,但qps量大,大厅服务与非状态服务之间通过消息队列、总线等方式进行通信
  • 匹配服务(matchServer):当玩家在大厅选择匹配后,将被加入到匹配服务中,并放入等待队列,一批玩家完成匹配后,会根据各个玩家所处位置,选择一个时延较小的区域进行游戏。
  • 战斗模块(BattleRegion):给玩家提供正式游戏体验的服务,由于FPS游戏对时延的敏感性较高,因此往往需要在不同的地区部署多个服务器集群,以供玩家就近接入,有效缩短物理延时。如遇到不同地区的玩家加入同一局游戏的情况,则可在匹配阶段寻找一个离各方较近的服务集群

延时处理策略

由于网络延迟、硬件运行、游戏实现逻辑等因素,使得如玩家点击鼠标开枪到产生实际效果之间存在一段时间的延迟,延时的长短也直接决定了游戏体验的高低。一般需要通过一些方式来降低延时。

  • 搭建专网
    • 网络包通过公网传输,一般需经过复杂的路由,因此大型游戏厂商一般会围绕玩家就近部署很多接入服务器,内部的服务器之间由专用的高速通道相连,相比公网的延迟可以大大降低。
  • 使用UDP
    • 相比TCP,UDP在剔除/简化了的拥塞控制以后,包传输的及时性有了明显的提升,尤其是在弱网环境下。对于需要可靠传输的场景可使用Reliable-UDP。
  • Buffering机制
    • 网络游戏中,客户端和服务器几乎每一帧都在通信,玩家的操作永远来自于客户端,权威的信息永远来自于服务器。但网络通信是不稳定的,服务器可能连续5帧都没有收到客户端输入,但下一帧又连续收到5个。这种输入的缺失和爆发增长会导致卡顿
    • Buffering机制是通过引入一个buffer,缓存几帧数据以后再以稳定的频率向服务端业务系统提供输入,这样可以有效解决网络延时带来的抖动。

战斗高并发场景

如果在一个场景中出现了大规模聚集的玩家,例如国战场景,那么必然会导致该场景的服务端压力比常规高很多,需要考虑战斗的高并发处理

  • 切分cell:参考无缝世界的方案,将大场景划分成cell,不同cell用不同进程来处理。
  • 提升单进程承载能力:比如逻辑优化、使用 C++ 写游戏逻辑等。
  • 服务降级:简化游戏逻辑,比如国战时只要确保核心战斗逻辑通顺,例如一些外观装备等信息可以不再同步。

设计策略

在实际应用中,有些业务场景的问题是技术上较难规避的,这时候可以考虑从设计角度来缓解此类问题,例如比较典型的Peeker’s advantage


  • 如上图所示,当蓝色玩家(peeker)从拐角出现时,红色玩家(holder)正蹲在角落埋伏。但在出现的极短时间内,由于蓝色玩家的位移操作仍在网络中进行同步,因此红方客户端的蓝方角色正处在拐角墙后,导致蓝方可以获得一个先手射击的优势。
  • 在技术层面,通过降低网络延迟的策略可以一定程度缓解这个优势,但理论上无法彻底杜绝。
  • 但从设计角度,可以有很多策略来规避
    • 地图设计:一个区域只留一两个入口),但场地内有多个设伏的地点。这样的设计可以使得holder埋伏的位置高度不确定,peeker出现的位置相对确定,变相地增加了peeker方的难度,抵消了先手优势。
    • 降低移动射击准确率:这样可以确保peeker在先手的短时间内,较难击中holder。
    • 让peeker的身体先暴露:例如降低人物移速、身体做大一点等,这样可以让peeker的部分身体先出现在拐角,但peeker的客户端视野仍有大半被拐角挡住,无法先手发现holder

相关推荐

相关文章