游戏项目的压力测试

作者:网易游戏雷火事业群
链接:https://zhuanlan.zhihu.com/p/503044178
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

1.服务器压力测试

由于游戏代码需要处理的数据量随人数增加,因此同一时刻参与人数较多的玩法和功能容易引起服务器负载过高,比如抢红包、登陆排队、多人战斗等。当服务器负载高时会严重影响玩家体验,甚至引发逻辑错误问题。参与人数较多的重要模块外放前,对其进行服务器压力测试是保证游戏口碑的必要步骤。

2.客户端压力测试

当同屏玩家数量较大,或者 UI 操作涉及的数据较多时,都可能引起客户端卡顿,需要模拟相应操作并进行客户端性能测试。具体玩家数量的阈值标准由游戏实际帧率情况决定。

3.第三方服务测试

游戏中的第三方服务是指,部分通用功能的实现通过调用第三方接口完成。

4.云游戏测试

当云游戏平台压力过大时,可能造成排队资源无法释放、黑屏和连接服务器失败等问题。下图为云游戏压测时的客户端情况:

压测性能指标

压力测试时,需要关注哪些游戏性能数据呢?有以下几个指标:

1.CPU、内存、IO 和流量

当游戏并发操作数量提升时,服务器和客户端的 CPU、内存、IO 和网络流量都会随之增加,也可能成为游戏进程的性能瓶颈,因此需要重点关注。

2.游戏进程LOG信息

游戏 LOG 中存储了一些判断游戏性能的重要指标信息,压测中主要关注的包括:

游戏 LUA 内存:LUA 的 collectgarbage("count")返回结果,如果测试过程中持续增大则说明有泄漏风险。 游戏在线人数:也是重要的性能指标,因为当服务器压力过大时可能导致玩家异常掉线。 游戏 CPU:逻辑线程的 CPU 负载情况,数值越大则表示负载越高。 数据库待执行的查询请求数量:此数量如果一直增加,则说明当前游戏处理请求的能力跟不上请求产生速度,故请求会一直堆积;查询待执行越久则玩家等待越久,因此这个数量等于 0 或保持在较低数值(<10)比较理想。 案例分析:在压测某个数据库操作频繁的玩法时,需要测试服务器对数据库请求的极限处理能力,以便于调整玩法 CD。一般操作是,逐步缓慢增加测试的并发数量,以保持数据库 LOG 的待执行查询数量在刚好等于 0,但是再增加并发则要排队的状态。实际操作发现难度系数较大,于是反其道而行之:让请求堆积到一定数量之后停止脚本,再根据两条 LOG 之间的变化值除以时间间隔,计算得出当前机器每秒处理数据库请求数量的上限值。 游戏 DELAY:游戏逻辑推进时间落后真实时间的秒数,DELAY 数值越大说明进程越卡;或者 CPU 虽然已经达到 100%,但是 DELAY 一直保持较小(<1),则说明游戏可以承载当前的并发操作数量。 案例分析:
某次压测任务是,需要比较三种不同型号 CPU 处理游戏运算的性能情况。一开始的策略是,在每种型号的 CPU 上都跑相同并发数量的测试用例, 在没有 DELAY 的情况下比较 CPU 负载绝对值;但是测试结果与预期并不相符。经过分析发现,操作系统调度优化策略会导致在没有 DELAY 的情况下,CPU 负载绝对值高低并不能真实反映 CPU 性能。于是变更测试思路,改为测试在游戏出现DELAY 的情况下,比较相同时间和并发量时的 DELAY 增长幅度,最终测试结果符合预期,如图:

3.客户端帧率

对于客户端而言,帧率是最重要的性能指标。研究表明人眼可视帧数不超过30 帧,因此当客户端帧率低于 30 帧时,则认为需要优化。

帧率记录最好可以覆盖多个变量,因为不同的机器配置、画面设置、可显示人数下,帧率会有比较大的差异。

4.游戏真实体验

真实体验也是非常重要的一环,某些问题不使用真实客户端体验可能会比较难以发现。

案例分析:在某游戏上线之前的一次登录模块压力测试中,服务器性能看起来非常良好,但是用客户端手动操作观察到,重登陆操作的队伍进度异常缓慢。分析服务器 LOG 发现,重登陆的次数远低于预期值。经过程序分析得知,是因为重登陆的请求都排队至同一个数据库连接导致。

压测机器人

压力测试中普遍使用机器人模拟真实玩家进行操作,主要有两种:服务器机器人和客户端机器人。

1.服务器机器人

是一种没有客户端的机器人,但是服务器端和正常玩家无异,通过 PATCH 登陆流程中和客户端的交互部分创建。

服务器机器人的优点是:涉及的代码量比较少,维护方便;创建操作快捷方便,只需要一行指令;由于没有客户端,因此不需要额外的硬件资源。

相应的缺点是

缺少服务器和客户端进行交互的 RPC 操作,使得服务器负载会低于真实情况。 无法估计服务器和客户端通信的网络流量负载。 只能通过服务器 AI 控制,对服务器性能有一定影响。

主要用途是

客户端性能测试

涉及多玩家的外观测试,如玩家穿着特定材质时装、装备发光武器和挂饰等;或者涉及多玩家的 UI 界面性能测试。

服务器压力测试

多玩家参加的玩法。虽然服务器 AI 会占用服务器资源,但是由于 AI 一般运行在服务器负责逻辑计算的进程,因此可以用来压测其他服务器进程的性能,比如测试需要进行大量数据库操作的玩法。

2.客户端机器人

首先客户端机器人为了性能考虑,删除了非常耗费资源的渲染相关代码;其次对产品代码进行了修改,让一个客户端机器人进程里可以同时存在多个主角对象。

客户端机器人的优点是:更加真实,因为所有的客户端服务器交互部分都得以保留;由于可以用客户端 AI 控制,因此不会影响服务器性能。

缺点是:改动的游戏代码比较多,需要一定维护成本;需要额外的硬件资源。客户端机器人目前主要用途是多人任务和战斗的服务器压力测试。

看到这里,相信大家对端游的压力测试已经有了一个基本的了解,接下来将为大家分享如何去进行压力测试及测试结果的分析。

压测执行

完整的压力测试流程应该包括的步骤为:沟通需求、明确方案、执行测试和撰写报告。

1.沟通需求

在玩法或功能规划之初,对于符合压测条件的,由策划开单提出压测需求。

首先需要了解测试玩法或功能的预估并发数量。比如某个玩法策划预计全服参与人数是 2 万人,则实际测试时最好比预估人数再多一些,保留一些余量。

然后是确认操作成功的标识。比如测试的玩法预计 2 万玩家参加,但是由于脚本的原因使得实际参与人数不足 2 万,则对服务器的性能判断会有偏差;因此在这个例子中,需要和相关人员了解如何确认成功参加玩法的玩家数量,保证测试操作的数据量级有达到需求。

接下来是和策划程序沟通之后明确可能产生压力的操作,通常是会引起高并发量的玩家行为;比如抢红包玩法,当全服在线玩家同一时间点击红包时服务器压力较大。操作明确后则可以编写对应的测试脚本。

最后是和程序确认各种操作可能产生压力的进程是哪些,测试的时候则需要重点关注。

以mmo游戏为例,常见的需要进行压力测试的条件有以下这些 :

客户端压力测试

新场景的投放 现有场景的大量资源修改,比如氛围更换导致较多植被和建筑变化 可能占据 50%以上视野的新渲染类型,比如新时装材质、新天气或者新特效 涉及 50 人以上的新界面,如帮会联赛约战房间

服务器压力测试

单个场景参与人数超过 50 的新玩法 涉及全服玩家、可能同时产生海量并发请求的操作;比如多人同时抢红包,或者对全服甚至所有服玩家进行信息同步的玩法

2.明确方案

首先需要明确模拟玩家操作的途径,比如:

压测服务器时优先选择客户端机器人可以更为真实地模拟 压测客户端时优先选择方便创建的服务器机器人 压测第三方服务可以使用构造 HTTP 请求方式

然后是沟通测试涉及的数据需求,确定哪些数据会对玩法性能产生影响,比如等级修为高低、装备评分、帮会等级和成员数量等;

最后是确定需要模拟的行为模式,以便于编写测试脚本。比如模拟玩家战斗, 要明确具体的技能释放策略;比如压测聊天系统,则要了解发送的频率和长度等。

3.执行测试

实际测试时,首先确认压力量级是不是达到了预期,然后查看游戏进程的性能,并进行采样分析,找到占比较高的模块后通知负责程序进行优化。优化完成后继续测试-采样-优化的步骤,直到游戏性能达到最佳状态。

压测第三方服务时要特别注意两点:首先需要和对方确认发送和接收的数量以保证一致,比如有网络问题导致发送到第三方的数据量降低,则会影响第三方对服务器性能的判断。其次是发送请求的游戏进程不能有延时,如果游戏进程比较卡,则发送的请求数量会偏少,进而影响第三方对于外网真实情况的预估。

4.撰写报告

最后是将测试流程和结果撰写报告,便于相关人员了解情况和日后复盘。

压测性能分析工具

当压测发现游戏性能问题时,目前常用的工具有:LuaProfiler(游戏进程的 CPU 和内存分析)、Perf(Linux 进程的性能分析)、VTune(Windows 进程的性能分析)、ProfilerAnalyzer(客户端的 CPU 和GPU 性能分析)和LuaDump(游戏进程的 LUA 内存占用分析)。

1.LuaProfiler

LuaProfiler 是由本组程序开发的性能采样模块。主要思想是 HOOK 需要关注性能的函数,在函数开始时记录当前时间和内存信息,然后调用原函数,原函数执行完成后再记录当前时间和内存信息。如此可以计算得出调用这个函数花费的时间和内存,还可以知道在采样的一段时间之内调用此函数多少次。

将这些信息记录到文件并使用脚本进行分析,可以得到 CPU 和内存使用情况,生成下图所示的火焰图。其中纵轴表示调用堆栈关系;横轴表示资源占用情况,越宽则说明占用越多,存在优化可能性。

下图中 d()的宽度大,但是它直接耗用 CPU 的部分很少,同理 b()和 c()没有直接消耗 CPU。因此,如果要优化性能问题,首先应该处理顶层最宽的 g(), 其次是i()。另外从图中可知,a()有两个分支 b()和 h(),这表明a()里面可能有一个条件语句,而 b()分支消耗的 CPU 大大高于 h()。

(转自http://www.ruanyifeng.com/blog/2017/09/flame-graph.html)

2.Perf

Perf 是内置于 Linux 内核源码树中的性能剖析(profiling)工具。它基于事件采样原理,以性能事件为基础,支持针对处理器相关性能指标与操作系统相关性能指标的性能剖析。可用于性能瓶颈的查找与热点代码的定位。linux2.6 及后续版本都自带该工具, 几乎能够处理所有与性能相关的事件 。

(转自https://blog.csdn.net/chichi123137/article/details/80139237)

Perf 指令可以对服务器进程的 C++引擎层面采样,分析后生成如下所示火焰图:

3.VTune

VTune 可视化性能分析器(Intel VTune Performance Analyzer)是一个用于分析和优化程序性能的工具,作为 Intel 为开发者提供的专门针对寻找软硬件性能瓶颈的一款分析工具,它能确定程序的热点(hotspot),找到导致性能不理想的原 因 , 从 而 让 开 发 者 据 此 对 程 序 进 行 优 化 。( 转 自https://blog.csdn.net/WY_stutdy/article/details/79106501)

4.ProfilerAnalyzer

此工具将客户端性能的相关数据输出并可视化,便于直观查看当前 CPU 或GPU 时间占用多的模块:

5.LuaDump

LuaDump 指令将各个类里的所有 table 变量长度打印输出。当内存泄漏情况发生时,可以分别对比内存变化前后的输出,集中分析增长异常的变量再细致排查。

结果分析与问题整理

压力测试过程中,可能发现的问题分为:

1.游戏报错或者崩溃

在测试数据量较大或测试时间较长的情况下,可能会出现一些在功能测试时难以发现的报错和崩溃;出现后将报错堆栈或崩溃文件给程序进行修改,并配合重现和调试。

2.内存泄漏

变量申请后没有正确释放则会造成内存泄漏问题,内存泄漏的进度在大多数情况下比较缓慢,因此较大的测试数据量和较长的测试时间是发现内存泄漏问题的关键。发现内存泄漏情况之后,用前面介绍的 LuaDump 工具进行内存分析,找到泄漏点再通知程序修改。

3.性能不满足要求

压测有可能发现性能不满足目标需求,此时可以有两种解决方案:优化代码或修改需求。

首先可以用之前介绍的 LuaProfiler、Perf、VTune 和 ProfilerAnalyzer 工具进行分析,找到当前占比较多的模块并通知程序修改。

案例分析:
某次客户端性能测试中发现,在某个 NPC 周围时客户端帧率平均值较低,借助常用的 VTune 和 ProfilerAnalyzer 客户端性能分析工具均未能准确定位到问题。经过仔细观察注意到,帧率呈现一定周期性变化规律;于是使用LuaProfiler 工具进行一段时间的采样分析发现,是由于 NPC 每隔几秒执行的冒泡代码会进行策划表改写操作导致。

其次可以和策划商量修改需求。

案例分析:
在一个类似 QQ 漂流瓶玩法的压测中,发现当未读瓶子数量足够巨大后,对瓶子数据进行匹配操作时服务器负载会比较高,于是与策划达成共识后决定牺牲一定随机性换取性能。优化前版本将所有待匹配漂流瓶存储在一个数组中,每次随机选择其中一个瓶子,并且需要依次移动之后的数据;优化后的算法为,将数据存储在 N 个数组中,每次随机抽取其中 1 个数组最后的数据。最终版本性能达到预期目标,外网运行情况良好。

4.负载不均衡

比较常见的负载不均衡现象是,当一个玩法需要开启较多副本时,在多个进程上数量分布差异较大,导致副本多的进程延时较高,进而影响玩家体验。

常用的处理方式为,结合进程负载和同类型副本数量进行选择:创建副本前,首先判断进程上已有的同类型副本数量,排除超过阈值的进程;然后从剩下的进程中选择负载最低的进行创建,以实现负载均衡。

5.高负载导致逻辑错误

在说这个问题之前我们先看一下具体案例:

案例分析:

QA 需要打一个外网 PATCH,但是 PATCH 内容拷贝出错了没有复制完整,导致打到外网之后服务器开始大量报错,进而服务器卡住。玩家跨进程传送时,是将玩家数据先在一个进程销毁然后再在另一个进程创建,由于服务器太卡就导致玩家跨进程时掉线,并且同时数据也没有及时销毁。此时玩家重新登录,就在另外一个进程有了新数据,相当于同一个玩家在一个服务器有了两份数据,为各种不合理操作埋下伏笔。

此次事故的后续改进措施为:

所有 PATCH 改用提交 SVN 的方式传递,并优化 PATCH 工具直接对文件而非字符串操作,以彻底杜绝拷贝出错的可能性 优化游戏报错模块,重复报错只打印一次详细堆栈,减少服务器卡顿程度 增加超级 ADMIN 端口,服务器出现大量报错导致卡顿时,优先处理此端口指令以快速修正报错 服务器增加玩家唯一性判断,防止存在同一玩家的多个实例

从此案例得到的启发是,可以通过压力测试的方式增加游戏负载,并配合功能测试,以发现高负载情况下可能的游戏逻辑漏洞。

相关知识

《第五人格》视障儿童公益捐赠支持项目的进展更新
暗黑破坏神4压力测试什么时候开始介绍
游戏&软件测试到底是什么?游戏测试理论详解来了!
游戏测试用到什么数据库
压力清洗好玩吗 压力清洗玩法简介
压力清洗机好玩吗 压力清洗机玩法简介
我的世界石头压力板有什么用
压力玩具销毁好玩吗 压力玩具销毁玩法简介
心理健康无压力好玩吗 心理健康无压力玩法简介
击败压力坐立不安好玩吗 击败压力坐立不安玩法简介

网址: 游戏项目的压力测试 http://www.hyxgl.com/newsview332718.html

推荐资讯