发布新日志

  • 网络游戏性能测试方案

    2011-02-15 20:34:19

    通过一轮的服务器性能测试,有些心得,总结一下分享给大家,有什么错误或者建议,请指出。

     

    针对当前游戏的架构,要开展性能测试,就需要先分析当前架构下,预计会出现哪些性能风险,服务器端和客户端分开进行分析。

    服务器端:内存消耗、Cpu占用、登陆压力、单服承载、同屏承载、同地图承载、带宽

    客户端:流量、帧数(FPS)、内存消耗、Cpu占用、流畅度

     

    .服务器端

    服务器端采用的是多线程,分为逻辑线程和网络线程,分开分析:

    1.逻辑线程:

    假设服务器设定每个心跳耗时200毫秒,即15个心跳,这是一个固定值。一个心跳循叫一帧,如果某帧需要处理时间为100毫秒,那么服务器就有50%的空闲时间;再如果某帧需要处理200毫秒,那么该线程的cpu占用则为100%。也就是说,如果服务器一帧需要的处理时间为5秒钟,那么客户端发送过来的请求经过处理后收到反馈需要的时间为(5秒+消息在网络上来回消耗),即传说中的服务器卡。

    那么,要验证逻辑线程卡不卡,或者要找出某负载下逻辑线程卡的原因,则需要记录各种逻辑处理所消耗的时间。目前服务器逻辑消耗主要在玩家和怪物逻辑上,因而需要记录的数据有怪物数量、总逻辑耗时、怪物逻辑耗时、玩家逻辑耗时和其他逻辑耗时。设计用例时则需要考虑不同负载下和无人空跑时的以上耗时的数据采集。

    采集到这些数据后,可以得出逻辑线程cpu占用,怪物耗时占用百分比,玩家耗时占用百分比,并进行分析,如果发现怪物耗时过多,则可以通过增加怪物休眠功能、减少怪物巡逻频率、减少怪物数量等方式来降低消耗;如果发现玩家耗时过多,则需要分析是哪一块玩家逻辑导致,必要时可以增加细分的玩家耗时log来获取数据进行分析。

    2.网络线程:

    假设1个角色每秒产生的消息条数为a条,那么X个角色同时在线的话,产生的总消息条数Y大概为:Y=a*x;而每个角色产生的a条消息,又分为需要广播和不需要广播的。

    需要广播的消息在处理后放大n倍,如移动消息,处理完毕后需要同步给周围的角色,如果周围有m个角色的话,消息条数就由1àm,最极端的情况为消息需要同步给全服角色,消息条数会由1àX;又如私聊消息是一对一,因为不需要广播,所以处理完毕后就不会使信息量放大;最极端的情况,全服的全部角色产生的消息都是需要全服广播的,比如全部玩家都在世界频道喊话,那么产生的消息量为Y=a*X*X

    那么,要验证网络线程卡不卡,或者要找出某负载下网络线程卡的原因,则需要记录各个消息在一定时间内一定负载下的发起数量、分发数量;网络线程耗时、各种消息单种的总耗时、耗时均值、峰值;消息是否为同步消息;另外我们还可以记录当前服务器消息堆积数,以及堆积的消息种类和数量。

    通过这些数据,我们可以得出网络线程cpu占用百分比,同步消息的平均同步次数;全部消息中,同步给全服的消息、同步给周围的消息、不需要同步的消息占整体消息百分比;

    通过这些数据,我们可以哪些消息导致瓶颈,哪些问题导致消息量过大等;通过平均同步次数,可以得出同屏人数瓶颈、同地图人数瓶颈等;通过不同负载下的数据,还可以得出性能数据趋势,也就是说可以通过500人数压力的负载得出的数据,推断出7001000人数负载下的性能数据;同时,我们还可以通过采集到的数据,分析哪些消息耗时高,哪些消息数量大。得出以上结论后,就可以有依据有针对性的进行相关优化。

    举例:服务器在300机器人全部世界聊天时,网络线程耗时过高,消息响应延迟非常严重,但是服务器采集到的消息堆积数为0,也就是说无消息堆积。

    分析:问题肯定是出在网络线程,通过代码分析,发现服务器全部接收了全部消息,所以消息没有堆积,但是服务器接收了消息后,无法全部快速处理完,所以导致了消息响应延迟严重,就像是部门经理把手头的100个任务全部丢给1个人处理,经理手头是没有任务堆积,但是那个手下由于无法快速处理完这些任务,导致任务响应很慢。

    进一步分析,发现消息主要耗时分2块:网络库消息的发送和服务器对消息的处理,比例为7:3

    问题找到了,负责网络库的研究网络库的性能,负责服务器的程序找出对应瓶颈。也可以采用另一种方案,那就是限制全服同步的消息的产生,只不过这个只是一个迫不得已的方案而已

    3.接下来分析内存风险,以现在的配置,服务器内存占用的多少不用过多考虑,主要要考虑的是内存泄露,主要通过查看一点压力下运行一段时间的内存变化情况来检查

    4.服务器带宽的评估,可以通过记录每个一段时间内收到和发送给客户端的数据包大小和数量来计算出每秒的数据量,然后换算出需要的带宽。bpsbyte per second。需要分析的是每秒byte数,现有网络,1m的带宽(单位是bit),带宽数值跟流量的比例理论上为:流量=带宽/8,加上损耗,能到达的最大流量大概为100K

    5.最后一个登陆压力,主要是验证登陆系统对于大量登陆请求的响应情况。当前情况下不用考虑,因为有已经运营的产品在验证。如果考虑这方面的性能测试的话,应该从一定负载下登陆系统的响应情况来考虑,比如100/500/1000机器人批量账号验证、批量创建角色、批量登陆游戏,采集这些数据进行分析。

    6.总结,通过前面5个步骤的分析,对于前面提到的服务器端性能风险,都已经覆盖到了,剩下的就是根据这些分析设计性能测试用例了

     

    .客户端:

    流量:可以通过服务器端带宽分析得到的数据除以当前服务器人数得出单个客户端的流量

    帧数(FPS):每秒钟帧数,这个可以直接在客户端增加log获得

    内存消耗:查看客户端内存和虚拟内存占用,重点关注是否内存泄露

    Cpu占用:直接在任务管理器查看

    流畅度:分为客户端本身渲染是否流畅和发送给服务器的请求的响应是否流畅。本身的流畅度可以通过增加渲染元素(特效、模型等,还有就是周围玩家数)来确定问题所在或者瓶颈,服务器的响应问题是服务器端优化范畴,上面已经分析

     

     

    分析结果示例:

    第四组:共1组数据,297--336人,共592

    A.      消息。均值370689微秒,cpu占用均值37.06%

    B.      逻辑。均值147816微秒,cpu占用均值27.88%,总耗时130226423微秒。其中怪物累计耗时107310854微秒占82.4%cpu22.97%,玩家累计耗时21292940毫秒占16.35%cpu4.55%,其他累计耗时忽略。

    C.      同步消息平均同步9.42

    D.      消息耗时中,同步给自身的12.68%cpu4.7%,同步给周围的87.04%cpu32.25%,同步给世界范围的0.26%

    E.       怪物数2470

     

    采集的数据示例

    在线数、数据量和消息耗时等,在一个文档里输出:

    #******************************************************************************************************************************#

        在线玩家: 283个最大:   286         道具数:    67

    网络处理耗时: 363620微秒   最大: 2183180微秒      怪物数:  2544

    玩家处理耗时:  0微秒       最大: 0微秒        副本数  3

    怪物处理耗时: 113687微秒 最大: 155344微秒        地图数: 34

    队伍处理耗时: 24471微秒 最大: 28263微秒      公会数: 8

    副本处理耗时: 0微秒    最大: 0微秒        队伍数: 17

    事件处理耗时: 8277微秒     最大: 17958微秒

    公会处理耗时:  60微秒      最大:  74微秒

    管理包() 192501716911KB      管理包() 1764 1392KB

    客户包() 130232224670936KB   客户包() 2458001102008KB

    【协议号ID =ZP_PCMOVE_ASK ,【协议号数量】 =77019 ,【分发数量】=1318707 ,【协议号总耗时】 =70070339 微秒 , 【均值】 = 909 微秒, 【峰值】 =10091 微秒, 【是否同步】 =

        怪物累计耗时 :        106584657

        玩家累计耗时 :         17497538

        其他累计耗时 :          1111735

    开始时间:2010-10-22 11:21:26:212

    结束时间:2010-10-22 11:32:11:087

     

    逻辑数据采集:

    逻辑耗时(微秒)            105705

    逻辑耗时(微秒)            126279

    逻辑耗时(微秒)             96004

     

    网络数据采集:

    网络处理耗时(微秒)            132952

    网络处理耗时(微秒)            139074

    网络处理耗时(微秒)            127098

     

     

     

  • 网络游戏常规功能测试总结

    2011-02-13 23:32:29

     

    1.       先对策划案进行分析,也可以组织进行评审,主要以下几个方面进行,输出是新的策划案:

    a:需求描述是否具备完整性;(没有遗漏内容;或描述片面)

    b:需求描述是否有二义性;(没有让不同的人有不同的理解结论)

    c:需求描述是否是正确的;(需求之间没有冲突等)

    d:是否包含有非功能属性的需求;(性能,安全性,可靠性,易用性等)

    e:是否需求是可以验证的;(需求描述具备可测试性)

    f:需求是否可实现;

    g判断需求的必要性

    2.       编写用例之前,先跟负责该系统的程序沟通一下,让他说下对于整个系统,他的大概思路,主要逻辑是什么,需要增加什么配置,数据存储方式等,有利于对系统了解更深刻,用例也能全面一些,而且程序通过叙述,也能梳理思路,并发现一些问题

    3.       根据之前的了解,分析整个系统,细分功能点,得出测试分析文档,主要列出功能点细分、重点难点、风险点,以及一下测试需求,包括人力需求、时间需求、log需求、gm指令需求、配置需求等,以便于输出用例和进行测试准备。也不一定得有文档,但脑子里应该清楚这些

    4.       用例初稿写好后,邮件发给大家,让大家帮忙看看有没有什么遗漏,让策划看看预期结果是否跟需求一致等,根据大家的反馈,完善用例,必要时可以对用例进行开小会评审

    5.       如果有条件,在用例完成后,丢给程序一份,让他们读读,能减少很多问题的出现

    6.       模块提交到测试这边时,可以先和程序沟通一下,进行风险分析,从风险发生的概率,风险产生的影响两个角度对风险进行打分评级,对于风险系数高的部分作为后期的测试重点,并配置针对性的测试资源和测试方法

    7.       用例的设计和执行,需要关注模块间交叉的异常检查

    8.       用例的执行,在执行过程中,发现一些在用例上未体现的检查点,需要实时补充

    9.       执行完用例后,可以测试组成员间交叉进行用例执行

    10.    执行结果出来后,检查发现的bug是否能在用例上一一对应,发现有未对应上的bug,就说明用例遗漏了检查点,需补充

    11.    整个系统测试完毕后,把一些比较重大的bug,添加到对应检查项后面,警示下次跑用例时这些需要着重关注,也可以当作一次总结;

    12.    bug的产生原因、修改方式应该很清楚,对bug的类型(性能、功能、设计问题)必要时也需要进行分类,然后可以结合其他系统的问题,进行汇总分析,可以得出其他一些结论,如设计考虑不全面、程序思路不够清晰等等

    13.    当系统有调整时,需要体现到用例上去,而不是用例执行过后就不管了,另一方面也需要敦促策划更新策划案

     

    Ps:我有个习惯,喜欢问程序实现机制或者bug出现的原因。沟通方式一般都是跟程序聊天时,让他们给我介绍他手头上的活的思路,听他们说完,我会以测试的角度问一些问题,经常程序会一拍脑袋说,我靠,这问题还真没考虑。到了功能开发的差不多时,我会过去,坐在程序的电脑前,大概的玩玩新开发的功能。

    这样有几个好处:

    1.       可以进行缺陷预防,从根本上杜绝一些bug的出现。作为程序员,当他们开始开发某个系统时,如果自己都无法跟别人描述清楚自己的思路,那么他自己的思路肯定也不会很清晰,因而,跟人复述一遍自己的思路,既能让自己的思路更加清晰,也说不定能在复述的时候,能够发现一些自己考虑不足的地方;作为测试员,也能够从测试的角度提一些问题,避免一些bug的产生。

    2.       对于测试来说,了解程序的实现机制,能使自己理清思路,测试有重点、有针对性,设计的测试用例,也能覆盖的更全面

    3.       可以通过听他们的叙述,评估这个系统的可靠性。比如bug的修改,如果程序跟你不确定的说,大概是咋咋造成的,那么你在回归这个bug的时候,就需要注意了,因为程序自己都没底;再比如程序设计系统时,步骤多,存储过程复杂,那设计用例时就必须多考虑异常情况

    4.       一些bug出现后,能在版本提交前被发现而马上解决掉,减少跑流程耗费的时间;

    5.       可以更有效的掌握程序的开发进度;

    6.       节省时间,提高开发效率;

    7.       可以帮助程序员提交代码质量。

        沟通前需要做的工作:

    1.对于一些基础的开发知识,需要了解,不然有时听不懂对方在说什么;

    2.对于工作经验要时常总结,才能对他们的叙述给出有用的反馈或者自己能通过这些叙述得出一些需要注意的关键点;

    3.沟通时机需要选择,最好是闲聊时或者看程序不忙的时候,因为集中精力工作中,大家都不喜欢被打搅;

    4.总结、分析各个程序员的编码习惯,得出该程序员常犯的错误。

    到了后来,他们都会主动跟我说,他想咋咋实现,让我帮他们用另外的角度看看这样的方案有没有什么漏洞,需要注意些什么,特别是开始一个比较大的新系统时。到了开发的差不多时,会让我过去帮他看看有没有什么问题,有问题能马上处理。

     

Open Toolbar