游戏服务器开发的基本体系与服务器端开发的一些建议
来源:小新 时间:2022-06-23 09:12:22阅读:0
这几年身边有很多朋友web转向游戏开发。他们以前从未开发过游戏服务器,更不用说任何经验了,而从互联网上找到的例子或游戏知识是如此的少和分散。当他们进入游戏公司时,他们看起来很困惑。如果大公司更好,至少有人可以学习一些经验,但有些人直接进入小公司,甚至这些小公司只有他一个背景。他们肩负着公司游戏后端的研发和公司的成败。他们也尽了最大努力,他们也想把游戏后端做好。但因为我没有经验,我以为一开始我会做游戏服务器web差不多,但是过了一段时间,才发现代码太多,太乱了。当我看到代码时,我想重坑往前走。
在这里整理一些游戏开发的东西,希望对想开发游戏服务器的朋友有所帮助。
首先要明确游戏服务器的开发和传统web开发有着本质的区别。游戏服务器开发,如果没有经验,一开始根本没有一个明确清析的目标,不像web那样,有些明确MVC架构往往是为了尽快满足规划的需要,尽快实现功能,让游戏尽快运行。然而,随着功能的增加,旧代码的修改越来越频繁,游戏测试中暴露出一堆bug,更让人觉得无奈。这时,我们想到了重构和架构设计。
游戏的框架设计非常重要。良好的框架代码分析,责任明确,可扩展性强,易于调试。这将为我们的发展节省大量时间。如何设计游戏框架?也许每个游戏都不一样,但本质上是一样的。
对于游戏服务器的框架设计,我们首先需要了解游戏服务器框架的组成部分?游戏在线需要什么功能?有些人可能会说,只要游戏运行,访问服务器就没有问题吗?答案是否定的,游戏框架本身代表一个系统,包括:
系统初始化
游戏逻辑
数据库系统
缓存系统
游戏日志
游戏管理工具
公共服务组件
这个系统是必不可少的,它们共同为游戏的整个运行过程服务。让我们一点一点地介绍每个系统的功能。
一、系统初始化
在没有客户端连接的情况下,系统初始化是服务器启动时需要做的工作。基本上是读取配置文件,初始化系统参数。
但必须考虑的是:
系统初始化所需的参数配置在哪里,是在本地服务器还是数据库中;
服务器启动时,去数据库取;
修改配置是否需要重启服务器等。
二、游戏逻辑
游戏逻辑是游戏的核心功能实现,也是整个游戏的服务中心,它被开发的好坏,直接决定了游戏服务器在运行中的性能。那在游戏逻辑的开发中我们要注意些什么呢?
游戏是一种强大的网络交互业务。良好的底层通信可以最大限度地提高游戏的性能,增加单个服务器处理的在线数量,为游戏带来更好的体验,至少不容易因网络层而导致数据交互堵塞。我建议在这里使用它Netty,它是目前最流行的NIO框架,它的用法可以在我之前的文章中查看,这里就不多说了。
有些人怀疑代码也需要分层?当然,不同的代码代表不同的功能实现。目前的开发语言是面向对象的。如果我们把功能代码堆在一起码,它似乎很快就实现了功能,但在后期,如果我们想修改需求,或增加原始代码的新需求,它真的被我们自己打败了。因此,代码必须分层,主要包括以下层:
协议层,又称前后交互层,主要负责与前台交互协议的分析和返回数据。在这个层面上,基本上没有业务逻辑实现。与前台交互的数据从这个层面开始,并在这个层面结束。例如,您使用它Netty框架,那么Netty的ChannelHandlerContext即Ctx只能出现在这一层,他不能出现在游戏业务逻辑代码的实现中,收到客户的请求,在这一层分析所需的参数,然后将参数传输到业务逻辑方法,业务逻辑方法处理后,返回到客户数据,组织数据,返回到客户,使业务逻辑和网络层分离,业务逻辑只关心业务实现,也方便业务逻辑单元测试。
业务逻辑层,在这里处理真正的游戏逻辑,计算价格,清关,计时。保存数据的保存数据。但这一层并不直接操作缓存或数据库,而是处理游戏逻辑计算。由于业务逻辑层是整个游戏事件的核心,他的处理是否正确直接决定了游戏的正确性。所以这一层的代码应该尝试使用面向对象的方法来实现。不要复制和粘贴重复代码或类似的功能,所以修改非常不方便,可能是修改某个地方,忘记修改相同的代码。还要考虑每种方法都是可测试的,一种方法的行数最好不要超过100行。此外,你可以阅读更多关于设计模式的书籍,它可以帮助我们设计一个灵活整洁的代码。
三、数据库系统
数据库是存储数据库的核心,但游戏数据通过网络和磁盘存储到数据库IO,与内存相比,其访问速度非常慢。一般来说,每次访问数据库数据库建立连接。访问完成后,为了节省数据库的连接资源,应断开连接。
这实际上增加了服务器的成本,在大量的数据访问中,可能会更慢,游戏需要低延迟,那么我们该怎么办呢?我们想到了数据库连接池,即将访问数据库的连接放在一个地方进行管理。用完后,我继续打开它,去那里拿,然后把它放回去。所以你不必每次都建立一个新的连接。
然而,如果我们想自己实现一套连接池管理组件,我们需要时间不说,技术控制也是一个测试,但也通过测试等等,幸运的是,今天的互联网开源,有一些现成的可以使用,这里推荐Mybatis,即实现代码和SQL有足够的分离SQL灵活性是一个不错的选择。
四、缓存系统
在游戏中,客户端和服务器之间的交互需要较低的延迟。延迟越低,用户体验就越好。正如我之前所说,低延迟要求服务器处理业务尽可能快,客户端要求在最短的时间内响应结果,最低不得超过500ms,因为加上来回的网络传输耗时,基本上是600ms-到700ms再长玩家也会觉得游戏卡。
如果您直接从数据库中获取数据,并在处理后将其存储回数据库,则该性能无法跟上。在服务器中,数据在内存中处理最快,因此我们应该提前将一些常用数据加载到内存中,如游戏数据配置表、经常登录的玩家数据等。这样,在处理业务时,您就不需要访问数据库,直接从内存中获取,速度更快。
游戏中有两种常见的缓存:
直接存储数据jvm或服务器内存
这里推荐使用第三方缓存工具Redis,详细用法可自行查询。
五,游戏日志
日志是一件好事。日志在游戏中不可或缺,日志必须详细记录。这是玩家在整个游戏中的行为记录。有了这个记录,我们可以分析玩家的行为,发现游戏的不足。在处理游戏中玩家的问题时,日志也是一种很好的凭证和快速处理方法。
日志在游戏中分为:
系统日志,主要记录游戏服务器的系统情况。例如:数据库是否正常连接,服务器是否正常启动,数据是否正常加载;
玩家行为日志,比如玩家发送了什么请求,得到了什么,花了多少钱等等;
统计日志是对游戏中所有玩家某些行为的统计。根据这个统计数据,分析大多数玩家的行为,得出一些共性或差异,通过操作不同的活动来吸引用户。
在框架设计中,日志记录必须被视为一种强制性行为,因为如果不是强制性的,可能会因为某个功能而忘记添加日志,所以当这个功能出现问题时,或者操作一些向我们索要这个功能的数据库,这是愚蠢的。您必须添加需求并更改代码。日志必须设计一个良好的格式,日志记录的数据应该很容易读取和分解。日志行为可以用枚举来描述,并将这个枚举添加到功能的最终处理方法中作为参数,这样无论谁调用该方法,都必须添加参数描述。
俗话说,如果一个工人想做好事,他必须首先磨利他的工具。游戏管理工具是处理游戏运行中一系列问题的工具。它不仅用于开发人员,也用于运营。游戏上线后,我们需要对在线问题进行不同的处理。程序员不可能处理所有的问题,所以程序员想出了一种方法,为你制作一个工具,你喜欢处理谁。
六、游戏管理工具
由于游戏中遇到的问题,游戏管理工具是一个不断增长的系统。
但根据经验,必须有一些功能,如:
服务器管理,主要负责服务器的开关,服务器配置信息,玩家信息查询;
玩家管理,如踢人、封号;
统计查询、玩家行为日志查询、统计查询、次留率查询、邮件服务、玩家数据修改等。
根据游戏的不同要求,所有可以通过工具实现的都可以在游戏管理工具中实现。它是为所有服务器管理的。
游戏管理工具好,可以提高游戏运营中遇到问题的效率,为玩家提供更好的服务。
七、公共组件
公共组件是为游戏运行提供公共服务。
充值服务器,我们不需要服用一个充值,你不能提供多个充值服务器地址,与第三方公司对接,他们绝对不做,这是疯狂的啊;
还有运营活动时的礼包码;
还有注册用户的管理,玩家可以进入不同的区域。
这些都是为所有区域服务提供的服务,所以要单独做,与游戏逻辑分开,便于管理、部署和负载平衡。
还有SDK登录验证,现在手机游戏更多,与渠道对接验证,这往往很多http请求,速度慢,所以也要单独拿出来做,不要在游戏逻辑中验证,因为网络IO访问时间无法控制,http是阻塞请求。
因此,综上所述,游戏服务器至少由几个大功能模块组成:
游戏逻辑工程;
日志处理工程;
充值工程;
游戏管理工具工程;
用户登录项目;
公共活动工程等。
根据游戏的不同需要,可能还有其他的。在框架设计中,必须考虑系统的分布式部署,并尝试拆卸公共功能,以提高系统的可扩展性。
开发服务器端的一些建议
本文作为游戏服务器端开发的基本大纲,是游戏实践开发的总结。
第一部分——专业基础,用于指导招聘和实习考核;
第二部分-游戏入门,讲述游戏服务器端开发的基本要点;
第三部分-服务端架构,介绍架构设计中的一些基本原则。
希望能大家有所帮助!
一、专业基础
1.1网络
1.1.1理解TCP/IP协议
网络传输模型
滑窗技术
三次握手与断开连接的四次握手建立连接
在建立和断开连接过程中的各种状态
TCP/IP协议的传输效率
思考:
请解释DOS攻击与DRDOS攻击的基本原理
一个100Byte数据包,精简到50Byte,其传输效率提高了50%
TIMEWAIT如何解释状态?
1.1.2掌握常用的网络通信模型
Select
Epoll,边缘触发与平台出发点的区别和应用
Select与Epoll区别与应用
1.2存储
计算机系统存储系统
程序运行时的内存结构
计算机文件系统,页面结构
实现内存池和对象池的原理,应用场景和差异
关系数据库MySQL的使用
共享内存
1.3程序
对C/C 对语言有深刻的理解
对刻理解界面、包装和多样性,并有实践经验
对常用数据结构的深刻理解:数组、链表、二叉树、哈希表
熟悉常用算法及相关复杂性:冒泡排序,快速排序
二、游戏开发入门
2.1防御式编程
不要相信客户数据,一定要检查。作为一个服务器端,你不能确定你的客户端是谁,你也不能假设它是善意的,请保护自己。(这是判断服务器端程序员是否进入的基本标准)
一定要判断函数的传输参数和返回值的合法性,不要过于信任内部子系统和功能模块,要求低耦合、高内聚。
在插件式模块设计中,应建立模块功能的强度,以尽量减少模块间耦合。
2.2设计模式
自然的道法。不要迷信,迷恋设计模式,更不要生搬硬套
简化、简化、再简化,用最简单的方法解决问题
借大宝一句话:设计本天成,妙手偶得之
2.3网络模型
自造轮子:Select,Epoll,Epoll一定比Select高效吗?
开源框架:Libevent,libev,ACE。
2.4数据持久化
自定义文件存储,如梦幻西游
关系数据库:MySQL
NO-SQL数据库:MongoDB
存储系统的选择应考虑稳定性、性能和可扩展性等因素
2.5内存管理
禁止在运行过程中动态分配内存池和对象池
严格检查输入输出的指针参数,宁滥不缺
写内存保护,使用带内存保护的函数(strncpy,memcpy,snprintf,vsnprintf等)
严格防止数组下标越界
防止读取内存溢出,确保字符串\0结束
2.6日志系统
简单高效,大量日志操作不应该影响程序性能
日志不会丢失稳定,使服务器崩溃
完整,玩家必须记住日志的关键操作,理想情况是通过日志在任何时候重建玩家数据
开关、开发日志应加级开关控制
2.7通信协议
采用PDL(ProtocolDesignLanguage),如Protobuf,可同时生成前后端代码,降低前后端协议联调成本,扩展性好
JSON,文本协议,简单,自解释,无协调成本,扩展性好,包装过滤和写日志也很方便
自定义二进制协议,精简,传输性能高效,完全可控,几乎没有扩展性
2.8全局唯一Key(GUID)
准备好合服
便于跟踪道具,设备流向
每一个角色、装备、道具都应该是全局唯一的Key
2.9多线程与同步
同步处理消息队列
2.10状态机
强化角色的状态
检查和验证前置状态
2.11数据包操作
合并,合并同帧中的数据包,减少IO操作次数
单副本,尽量只保存一个包,减少内存复制次数
AOI中间过程无用数据包同步减少
2.12状态监控
随时监控服务器的内部状态
使用内存池和对象池
帧处理时间
网络IO
包处理性能
处理各种业务逻辑的次数
2.13包频率控制
瘫痪变速齿轮是基于每个玩家每个协议的包频率控制
2.14开关控制
每个模块都有开关,可以紧急关闭任何有问题的功能模块
2.15反外挂反作弊
变速齿轮可以通过包频控制
包id可消除自增校验WPE
可以消除或拦截篡改的包校验码
图形识别码可以踢掉99%的非人操作
魔高一尺,道高一丈
2.16热更新
防沉迷系统、包频控制、开关控制等核心配置逻辑的热更新
代码基本热更新,如Erlang,Lua等
2.17防刷
关键系统资源(如元宝、能量值、道具、设备等)的输出记录日志
尽量依靠两个或两个以上的独立条件来检测资源的产出和消耗
严格检查各项操作的前提
验证参数的合法性
2.18防崩溃
该系统的底层与具体的业务逻辑无关,可以通过大量的机器人压力测试来暴露bug,确保稳定
建议使用脚本进行业务逻辑
系统地保证游戏不会崩溃
2.19性能优化
IO操作异步化
IO操作合并缓写(事务性提交)db操作、包合并、文件日志慢写)
Cache机制
减少竞态条件(避免频繁进出切换,尽量减少锁定使用,多线程不一定是单线程),多线程不一定比单线程快
减少内存复制
自己测试,用数据说话,不要猜
2.20运营支持
接口支持:实时查询、控制指令、数据监控、客服处理等
提供考虑http接口
2.21容灾及故障预案
略
三、服务器端架构
3.1什么是好的结构?
满足业务要求
能够快速实现规划需求,响应需求变化
保证系统级的稳定性
简化开发。将复杂性控制在架构底部,降低对开发人员的技术要求,逻辑开发不依赖于开发人员强大的技术实力,提高开发效率
完善的运营支撑体系
3.2思考架构实践
简单,满足需求的架构是好的架构
设计性能,抓住重要的20%,不需要从程序代码中挖掘性能
热更新是必要的
人难免会犯错,尽量用一套机制来保证逻辑的健壮性
游戏服务器的设计是一项具有挑战性的工作,游戏服务器的发展也从以前的单一服务结构转变为多服务机构,甚至出现bigworld最近了解到了发动机的分布式解决方案Unreal服务器解决方案atlas也以集群为基础。
负载均衡是一个非常复杂的话题,这里就不谈了bigworld和atlas这种服务器的设计更多的是基于功能和场景来划分服务器结构。
首先,服务器划分基于以下原则:
在游戏中分离系统资源(cpu,内存,IO等)更多功能,独立成为服务器。
在同一服务器架构下的不同游戏中,应尽可能多地重用某些服务器(进程级重用)。
多核处理器适用于多线程并发编程。
宁愿在服务器之间复制更多的数据,也不愿保持清晰的数据流。
根据场景划分过程,如果需要按功能划分,则必须保持整个逻辑足够简单,并满足上述1、2点。
服务器结构图:
简要说明:
Gateway主要用于维护和应用网关client该服务器需要两种连接IO:
对client采用高并发连接,低吞吐量的网络模型,如IOCP等
对服务器采用高吞吐量连接,如堵塞或异步IO。
网关主要有以下用途:
分担了网络IO同时,还分享了网络消息包的加解密、压缩解压等cpu密集操作。
隔离了client和内部服务器组,对client它只需要知道网关的相关信息(ip和port)。client切换场景服务器等操作是正确的,因为它一直与网关保持连接client透明。
保持玩家登录状态。
WorldServer它是一个控制中心,负责将各种计算资源分配给各种服务器,其职责如下:
多种管理和维护SceneServer。
多功能服务器的管理和维护主要是将数据同步到功能服务器。
其他服务器和服务器的复杂转发Gateway之间的数据。
实现团队、聊天、帮派等需要跨场景的其他功能。
PhysServer主要用于玩家移动、碰撞等检测。
所有玩家的移动操作都在服务器上进行检查,因此服务器本身具有所有地图的地形和其他相关信息。具体的检查过程如下:首先,Worldserver收到移动信息,WorldServer收到后向PhysServer请求检查,PhysServer检查成功后返回worldServer,然后worldserver传递给相应的SceneServer。
SceneServer场景服务器,按场景划分,每个服务器负责的场景应该是可以配置的。理想情况下是可以动态调节的。
ItemMgrServer物品管理服务器负责所有物品的生产过程。在服务器上存储一个物品掉落数据库,并在服务器初始化时输入内存。任何需要生产物品的服务器都直接与服务器通信。
AIServer另一个负责管理一切的功能服务器NPC的AI。AI通常有两个输入:
一个是SceneServer相关操作信息发送给玩家
另一个时钟Timer驱动
对于其他服务器,AIServer一个有很多个NPC的客户端。AIserver所有和都需要同步AI相关的数据,包括很多玩家数据。由于AIServer的Timer可在很大程度上使用驱动特性TBB发挥多核性能的程序库。
将网络游戏服务器分为多个过程,分别部署。
该设计的优点是模块自然分离,可单独设计。负荷分担可以提高整个系统的承载能力。
缺点是网络环境不那么可靠。跨过程通信具有一定的不可预测性。服务器之间的通信通常很难建立一个调试环境,而且很容易把事情搅拌成一团糊状。正确和高效的管理对程序员来说也是一个挑战。
几年前,我还写了几篇与之相关的设计。这几天我在想一个问题:如果要做一个底层通用模块,后续开发会更方便。需求应该解决什么?这个需求应该是单一的、基本的,每个应用都需要。
正如TCP该协议解决了在互联网上稳定可靠的点对点数据流通信。游戏世界实际上需要的是游戏系统中稳定可靠的点对点通信需求。
我们可以在一个TCP做到这一点。一旦实现,就能给游戏服务的开发带来极大的便利。
游戏系统中的所有服务,包括不限于登录、拍卖、战斗场景、数据服务等,都可以被视为网络上的几个终端。每个玩家也可以是一个独立的终端。它们一起形成一个网络。在此网络上,终端可以可靠地连接和通信。
实现可以是这样的:
每个虚拟终端都在游戏虚拟网络中(GameNetwork)有一个唯一的地址(GameNetworkAddress,GNA)。这个地址可以提前设置,也可以动态分配。每个终端都可以通过游戏网络的多个接入点(GNAP)通过唯一的TCP连接到网络。
接入过程需要通过鉴权。
识别过程依赖于内部安全机制,可以包括密码证书或特殊的访问点。(例如,玩家需要一个特定的访问点来访问网络,该访问点的终端必须是玩家)
鉴权通过后,网络为终端分配一个固定的游戏域名。例如,玩家将被分配到player.12345数据库访问可以分配这样的域名database。
游戏网络默认提供一个域名查询服务(这个服务可以通过鉴权的过程注册到网络中),让每个终端都能通过域名查询到对应的地址。
然后,游戏网络中所有合法访问的终端都可以通过其地址相互连接和通信。
基于整个协议TCP在协议之上,工作在唯一的一个TCP连接。直接使用TCP连接是不同的。游戏网络中每个终端之间的相互启动连接是可靠的。玩家不仅可以连接到某个服务,反过来也可以。玩家之间的直接连接也是可行的(是否允许这取决于具体的设计)。
因为每个虚拟连接都是基于单一的TCP以上连接。因此,互联网的发起减少了TCP各种连接的不可靠性。鉴权过程也是一次性唯一的。
而且我们提供域名反查服务,我们的游戏服务可以清晰、安全地知道连接到谁。
该系统可以设计为离开游戏网络上的每个终端,域名服务将通知所有人广播这个消息。这种广播服务在互联网上很难实现,但在这个虚拟游戏网络中,无论是广播还是集体广播都是可行的。
在这个设计中。在逻辑层面上,我们可以让玩家直接将聊天信息从玩家客户发送到聊天服务器,而无需建立多余的信息TCP连接不需要对转发和处理聊天信息进行额外处理。聊天服务器可以独立存在于游戏网络中。广播服务也可以主动将信息推送给玩家,并由服务器连接到玩家,而不是所有的连接请求都由玩家和客户发起。
虚拟游戏网络的构成是一个独立的层次,完全可以撇开具体游戏逻辑来实现,并能够单独去按承载量考虑具体设计方案。非常利于剥离出具体游戏项目来开发并优化。
最后,我们可能需要一套C用于游戏网络中的通信。api可以和socketapi类似。额外的两个访问和离开游戏网络。
微云网络IDC提供香港服务器、美国服务器全球海外服务器租赁托管是区域链、直销、流媒体、外贸、游戏等服务器解决方案的首选品牌。微云网络已为许多企业提供区块链服务器租赁托管解决方案,为他们的区块链安全提供支持!咨询在线客服!
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:shawn.lee@vecloud.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
本站原创内容未经允许不得转载,或转载时需注明出处:https://news.kd010.com/fwqjs/10966.html