游戏服务器开发的基本体系与服务器端开发的一些建议

Tom发布于:2022-07-06阅读:0

这几年身边有很多朋友web转向游戏开发。他们以前从未开发过游戏服务器,更不用说任何经验了,而从互联网上找到的例子或游戏知识是如此的少和分散。当他们进入游戏公司时,他们看起来很困惑。如果大公司更好,至少有人可以学习一些经验,但有些人直接进入小公司,甚至这些小公司只有他一个背景。他们肩负着公司游戏后端的研发和公司的成败。他们也尽了最大努力,他们也想把游戏后端做好。但因为我没有经验,我以为一开始我会做游戏服务器web差不多,但是过了一段时间,才发现代码太多,太乱了。当我看到代码时,我想重坑往前走。

游戏服务器开发的基本体系与服务器端开发的一些建议

在这里整理一些游戏开发的东西,希望对想开发游戏服务器的朋友有所帮助。

首先要明确游戏服务器的开发和传统web开发有本质区别。游戏服务器开发,如果没有经验,一开始就没有明确的分析目标,不像web那样,有些明确MVC架构往往是为了尽快满足规划的需要,尽快实现功能,让游戏尽快运行。然而,随着功能的增加,旧代码的修改越来越频繁,游戏测试中暴露出一堆bug,更让人觉得无奈。这时,我们想到了重构和架构设计。

游戏的框架设计非常重要。良好的框架代码分析,责任明确,可扩展性强,易于调试。这将为我们的发展节省大量时间。如何设计游戏框架?也许每个游戏都不一样,但本质上是一样的。

对于游戏服务器的框架设计,我们首先需要了解游戏服务器框架的组成部分?游戏在线需要什么功能?有些人可能会说,只要游戏运行,访问服务器就没有问题吗?答案是否定的,游戏框架本身代表一个系统,包括:

游戏日志游戏管理工具公共服务组件系统初始化游戏逻辑数据库系统缓存系统

这个系统是必不可少的,它们共同为游戏的整个运行过程服务。让我们一点一点地介绍每个系统的功能。

一、系统初始化

在没有客户端连接的情况下,系统初始化是服务器启动时需要做的工作。基本上是读取配置文件,初始化系统参数。

但必须考虑的是:

系统初始化所需的参数配置在哪里,是在本地服务器还是数据库中;

服务器启动时,去数据库取;

修改配置是否需要重启服务器等。

二、游戏逻辑

游戏逻辑不仅是实现游戏的核心功能,也是整个游戏的服务中心。它的开发直接决定了游戏服务器在运行中的性能。在游戏逻辑的开发中我们应该注意什么?

游戏是一种网络交互比较强的业务,好的底层通信,可以最大化游戏的性能,增加单台服务器处理的同时在线人数,给游戏带来更好的体验,至少不容易出现因为网络层导致的数据交互卡顿的现象。在这里我推荐使用Netty,它是目前最流行的NIO框架,它的用法可以在我之前的文章中查看,这里就不多说了。

有些人怀疑代码也需要分层?当然,不同的代码代表不同的功能实现。目前的开发语言是面向对象的。如果我们把功能代码堆在一起码,它似乎很快就实现了功能,但在后期,如果我们想修改需求,或增加原始代码的新需求,它真的被我们自己打败了。因此,代码必须分层,主要包括以下层:

协议层,又称前后交互层,主要负责与前台交互协议的分析和返回数据。在这个层面上,基本上没有业务逻辑实现。与前台交互的数据从这个层面开始,并在这个层面结束。例如,您使用它Netty框架,那么Netty的ChannelHandlerContext即Ctx只能出现在这一层,他不能出现在游戏业务逻辑代码的实现中,收到客户端的请求,在这一层分析所需的参数,然后将参数传输到业务逻辑方法,业务逻辑方法处理后,返回客户端数据返回到这一层,组织数据,返回到客户端,使业务逻辑和网络层分离,业务逻辑只关心业务实现,也方便业务逻辑单元测试。业务逻辑层,在这里处理真正的游戏逻辑,计算价格,清关,计时。保存数据的保存数据。但这一层并不直接操作缓存或数据库,而只是处理游戏逻辑计算。由于业务逻辑层是整个游戏事件的核心,他的处理是否正确直接决定了游戏的正确性。所以这一层的代码应该尝试使用面向对象的方法来实现。不要重复代码或类似的功能进行复制和粘贴。因为业务逻辑层是整个游戏事件的核心,所以他的处理是否正确直接决定了游戏的正确性。所以这一层的代码应该尝试使用面向对象的方法来实现。这样修改起来非常不方便,可能是修改了某一处,而忘记了修改另外同样的代码。还要考虑每个方法都是可测试的,一个方法的行数最好不要超过一百行。另外,可以多看看设计模式的书,它可以帮助我们设计出灵活,整洁的代码。

三、数据库系统

数据库是存储数据库的核心,但游戏数据通过网络和磁盘存储到数据库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.掌握常用的网络通信模型

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数据持久化

自定义文件存储,如梦幻西游关系数据库: MySQLNO-SQL数据库: MongoDB存储系统的选择应考虑稳定性、性能和可扩展性等因素

2.5内存管理

使用内存池和对象池,禁止在运行过程中动态分配内存。严格检查输入输出的指针参数,使用带内存保护的函数(strncpy,memcpy,snprintf,vsnprintf等)严格防止数组下标越界,防止读内存溢出,确保字符串以/ 0 结束

2.6日志系统

简单高效,大量的日志操作不应影响程序性能的稳定性使服务器崩溃是日志不丢失完整,玩家必须记住日志的关键操作,理想情况是通过日志可以重建玩家数据开关,开发日志增加水平开关控制

2.7通信协议

采用PDL(Protocol Design Language),如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.什么是好的结构?

满足业务要求可以快速实现规划需求,响应需求变更系统级稳定性保证,简化开发。将复杂性控制在架构底部,降低对开发人员的技术要求。逻辑开发不依赖于开发人员强大的技术实力,而是依赖于提高开发效率和完善的操作支持系统

3.思考架构实践

简单地说,满足需求的架构是良好的架构设计性能。抓住重要的20%。没有必要从程序代码中挖掘性能。热更新是必要的。人们不可避免地会犯错误,并尽可能使用一套机制来确保逻辑的强度

游戏服务器的设计是一项具有挑战性的工作,游戏服务器的发展也从以前的单一服务结构转变为多服务机构,甚至出现bigworld最近了解到了发动机的分布式解决方案Unreal服务器解决方案atlas也以集群为基础。

负载均衡是一个非常复杂的话题,这里就不谈了bigworld和atlas这种服务器的设计更多的是基于功能和场景来划分服务器结构。

首先,服务器划分基于以下原则:

在游戏中分离系统资源(cpu,内存,IO等)更多的功能,独立成为一个服务器。在同一服务器架构下的不同游戏应尽可能重复使用某些服务器(进程级重复使用)。适应多线程并发编程的多核处理器。我宁愿在服务器之间复制更多的数据,也不愿保持清晰的数据流。主要根据场景划分过程,如果需要根据功能划分,则必须保持整个逻辑足够简单,并满足上述1、2点。

服务器结构图:

简要说明:

Gateway 是主要用于维护和维护的应用网关client该服务器需要两种连接IO:对client网络模型采用高并发连接、低吞吐量等IOCP等

对服务器采用高吞吐量连接,如堵塞或异步IO。

网关主要有以下用途:

分担了网络IO同时,还分享了网络消息包的加解密、压缩解压等cpu密集操作client和内部服务器组,对client它只需要知道网关的相关信息(ip和port)。client切换场景服务器等操作是正确的,因为它一直与网关保持连接client它是透明的。保持玩家登录状态。

World Server 是一个控制中心,负责将各种计算资源分配给各种服务器,其职责如下:

多种管理和维护Scene Server。多种管理和维护功能服务器,主要是同步数据到功能服务器。复杂转发其他服务器和Gateway之间的数据。实现其他需要跨场景的功能,如组队,聊天,帮派等。

Phys Server 主要用于玩家移动、碰撞等检测。

所有玩家的移动操作都在服务器上进行检查,因此服务器本身具有所有地图的地形和其他相关信息。具体的检查过程如下:首先,Worldserver收到移动信息,WorldServer收到后向Phys Server请求检查,Phys Server检查成功后返回world Server,然后world server传递给相应的Scene Server。

Scene Server场景服务器,按场景划分,每个服务器负责场景应配置。理想情况下,可以动态调整。

ItemMgr Server 项目管理服务器负责所有项目的生产过程。在服务器上存储一个项目掉落数据库,并在服务器初始化时输入内存。任何需要生产项目的服务器都直接与服务器通信。

AIServer 另一个负责管理一切的功能服务器NPC的AI。AI通常有两个输入:

一个是Scene Server另一个时钟发送玩家相关操作信息Timer驱动

对于其他服务器,AIServer一个有很多个NPC的客户端。AIserver所有和都需要同步AI包括许多玩家数据在内的相关数据AIServer的Timer可在很大程度上使用驱动特性TBB发挥多核性能的程序库。

将网络游戏服务器分为多个过程,分别部署。

这种设计的优点是模块自然分离,可以单独设计。分担负载可以提高整个系统的承载能力。缺点是网络环境不太可靠。跨过程通信是不可预测的。服务器之间的通信往往很难设置调试环境,很容易把事情搅成糊状。而正确高效的管理和多连接对程序员来说也是一个挑战。

几年前,我还写了几篇与之相关的设计文章。这几天我在想一个问题:如果要做一个底层通用模块,后续开发会更方便。需求应该解决什么?这个需求应该是单一的,基本的,每个应用都需要。

正如 TCP 协议解决了在互联网上稳定可靠的点对点数据流通信。游戏世界实际上需要的是游戏系统中稳定可靠的点对点通信需求。

我们可以在一条 TCP 在连接上做到这一点。一旦实现,就能给游戏服务的开发带来极大的便利。

游戏系统中的所有服务,包括不限于登录、拍卖、战斗场景、数据服务等,都可以被视为网络上的几个终端。每个玩家也可以是一个独立的终端。它们一起形成一个网络。在此网络上,终端可以可靠地连接和通信。

实现可以是这样的:

每个虚拟终端都在游戏虚拟网络中(Game Network)唯一的地址 (Game Network Address ,GNA) 。这个地址可以提前设置,也可以动态分配。每个终端都可以通过游戏网络的几个接入点 ( GNAP 通过唯一的 TCP 连接到网络。访问过程需要通过权利识别。权利识别过程依赖于内部安全机制,可以包括密码证书或特殊访问点的区别。(例如,玩家需要一个特定的访问点来访问该网络,该访问点访问的终端必须是玩家)权利识别通过后,该网络为终端分配一个固定的游戏域名。例如,玩家将被分配到 player.数据库2345 等域名,数据库访问可分配到 database 。默认情况下,游戏网络提供域名查询服务(该服务可以通过识别权利的过程注册到网络中),以便每个终端都可以通过域名查询相应的地址。然后,游戏网络中所有合法访问的终端都可以通过其地址进行连接和通信。整个协议是基于 TCP 协议上,唯一的 TCP 连接。直接使用 TCP 连接不同。游戏网络中每个终端之间的相互启动连接是可靠的。玩家不仅可以连接到某个服务,反过来也可以。玩家之间的直接连接也是可行的(是否允许这取决于具体的设计)。因为每个虚拟连接都是基于单个 TCP 以上连接。因此,在互联网上发起 减少了TCP 连接的各种不可靠性。权利识别过程也是一次性的唯一过程。我们提供域名检查服务,我们的游戏服务可以清楚和安全地知道连接到谁。该系统可以设计为游戏网络上的每个终端都离开网络,域名服务将通知所有人广播这个消息。这种广播服务在互联网上很难实现,但在这个虚拟游戏网络中,无论是广播还是组织广播都是可行的。在这个设计中。在逻辑层面上,在不建立多余 的情况下,玩家可以直接将聊天信息从玩家客户的互端发送到聊天服务器TCP 连接不需要对转发和处理聊天信息进行额外处理。聊天服务器可以独立存在于游戏网络中。它还可以让广播服务主动向玩家推送信息,并由服务器连接到玩家,而不是所有的连接请求都是由玩家和客户发起的。虚拟游戏网络的组成是一个独立的层次,可以完全抛开特定的游戏逻辑,并可以根据承载能力单独考虑特定的设计方案。非常有利于剥离特定的游戏项目来开发和优化。最后,我们可能需要一套 C 库,用于游戏网络中的通信。api 可以和 socket api 类似。额外多两条接入与离开游戏网络即可。

微云网络IDC提供香港服务器美国服务器全球海外服务器租赁托管是区域链、直销、流媒体、外贸、游戏等服务器解决方案的首选品牌。微云网络已为许多企业提供区块链服务器租赁托管解决方案,为他们的区块链安全提供支持!咨询在线客服!

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:shawn.lee@vecloud.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

本站原创内容未经允许不得转载,或转载时需注明出处:https://news.kd010.com/fwqjs/11359.html

TAG标签:游戏服务器服务器

上一篇:视频直播平台的服务器怎么选!
下一篇:高防服务器与CDN防御有什么区别?哪个更好用?

相关文章

返回顶部