第一章:性能测试与工具(翻译)1

#

选择什么来衡量

在搜集数据测试数据前,你需要知道你要以怎样的指标来衡量测试结果。这听起来很容易,但实际上比你想象中的要难许多。如果你想降低内存使用量,你会选择什么方式呢?

  • 私有工作集(Private working set)
  • 提交大小(Commit size)
  • 内存页(Paged pool)
  • 峰值大小(Peak working set)
  • 内存堆大小(.NET heap size)
  • 大对象堆(Large object heap)
    and so on

为了追踪内存的使用情况,我们还需要记录一个小时内的平均值和峰值?内存与处理器进程负载的关系?正如你所看到的,随便就能举出十几个甚至更多与内存相关的性能指标。

我们需要尽可能的准确描述要测试的东西

一旦你决定要测试某个产品,你需要为每个性能指标提出一个目标。在早期开发阶段,订立的目标可能不够准确,或者与实际情况不符。但重点是,不是说一定要达到一开始规划的目标,而是强迫你构建一套可以自动测试你说提出这些性能指标的体系结构。
你的目标应该是可量化的吗,你的程序目标也许是“快”,这个是一个不错的指标,但不是一个好的指标,因为“快”是一个很主观的因素,你没有一个明确的东西来表示你是否达到了快这个目标。你需要给目标定一个数字,并且这个数字是要可以测试出来的。

坏:“用户界面需要正常相应”
好:“任何操作不应该造成UI线程卡住超过20毫秒”

能量化还不够好,还需要有更具体的描述,例如下面说的内存指标

坏:“内存应小于1G”
好:“内存在 100次/秒的峰值查询情况下,内存使用不超过1G”

对于第二个例子,给出了一个具体的情景,要在这个情景下达成怎样的目标就是一个比较好的测试用例

另外一个重要的决定性因素,是你写的应用的目标是什么。如果是以一个带GUI界面的引用,那么你需要必须保证任何时刻都能响应用户的操作请求。如果你写的是一个每秒处理几百几千访问的服务器程序,你的目标就算要保证I/O和CPU的利用率在一个很低的范围内。如果你设计的是一个与市面上不一样的服务器应用,那么从效率的角度上看,一旦你的架构除出问题(性能上的),在重新修改架构就非常麻烦了。

在设计新系统时,我们需要对性能指标做一些规划。这时你需要了解一些会对性能产生影响的地方,例如CPU,内存,IO的使用率等情况。举个栗子,如果你有一台16核,64G内存的机器以及10G的网络带宽,这时候你需要设定好一个阈值,如“每秒可以处理多少数据”,这个可以在一台机器无法满足需要时,你知道你还需要多少台机器。这些信息都是你在做规划时需要写在规划目标里的。

你可能听过 _Donald Knuth 说过的:“过早优化是万恶之源”。但这只适合代码级别的优化。你必须清楚你在设计上的缺陷会对应用产生多大的影响。你必须把性能目标考虑到设计中。你必须在一开始时就有一个明确的目标。性能和安全以及一些东西时不能事后设计,否则你会被架构重构教会你做人的道理。

性能分析(设计)放在项目的开始,比在写完代码后进入测试阶段再考虑性能,思路是不一样的。在项目开始前,你可以设计出达到你想要的在性能上的扩展性,而不会陷入一些架构陷阱里(我暂时没明白这里说的架构陷阱是指那些东西)。在进入项目的测试,部署和维护阶段,你才有更多的时间在代码层级的优化上,对热点函数代码做分析,减少cpu,内存的消耗。

最后,你需要了解Ahmdals定律(See [pdf]:http://www.writinghighperf.net/go/3),特别是如何适用于顺序(序列化)编程以及选择哪个部分进行优化。在代码级别的优化堆整体性能用处不大,甚至会浪费时间。但你总是希望优化代码里效率最低的那部分。不过,聪明的你应该会知道,你不会有足够时间去干这件事情。这就是为什么你需要有一个好的性能监控系统(工具),否则,你甚至不知道从哪里改起。

平均值 vs 百分比

在考虑要性能测试的目标值时,我们需要考虑用什么统计口径。大多数人都会首选平均值,但在大多数情况下,这个正确的,但你也应该适当的考虑百分数。但你有可用性的要求,作为性能测试的目标里肯定会有用百分比作的要求。举个栗子:“数据库请求的平均延迟必须小于10ms,95%是请求必须小于100ms”
。。。(这里我省略了对“95%是请求必须小于100ms”的翻译说明,我觉得中国的程序猿应该看得懂我翻译的那句话)

1,2,2,4,5,5,8,10,10,11,11,11,15,23,24,25,50,87

举个栗子,上面有18个测试下来的值(已经过排序了的),的平均耗是17ms,但有5%的访问超过50ms。如果你刚好只看平均值,你一定会认为一切正常。但当你用了百分比作为指标,你就会知道一些偶发的GC操作会影响到你的访问质量。

百分比是高可用性的最重要指标。如果你需要更高的可靠性,就需要提出一个更高的百分数指标。通常来说99%已经很好了,但你还会可能有99.99% 99.999%,甚至更高的指标,但通常来说,决定采用这些指标数字取决于业务,而不是开发。

这里作为翻译的我,来补一些关于百分比的数据
99% 允许每年服务器挂 3.65 天(多让人尴尬的数据啊,但我相信很多公司服务器不一定达能到这个要求)
99.9% 允许每年挂 8.76 小时(1年出了一次较大的事故,基本就用完额度了)
99.99% 允许每年挂 52.6 分钟(1年只能出一次小的事故,还得是能立即解决的)
99.999% 允许每年挂 5.26 分钟(如果真的发生小于这个时间的事故,对于用户来说一般很难有感知,但是在淘宝双十一零点之后的一个小时内碰上的话 (=@__@=) )
99.9999% 允许每年挂 31 秒(写一个程序在一年的时间里只往控制台输出 hello world的同时还得祈求上帝保证机房不要断电 O(∩_∩)O!)

百分比是一个重要的指标,是因为他可以帮助你了解你的系统,即使通过平均值观察到,你的系统一切正常,但是只有90%的用户访问满足了目标,也会意味着,你还有10%的用户访问还有可以改进的空间。要解决这这部分请求问题,需要的更多是商业上的考量,因为这里会存在一个递减回报的问题,因为提升最后的1%要花的时间不是一般的多。

对于上面的例子“有95%的访问请求满足了50ms以内的需求”,但数据源来说,不符合统计学上对样本数量的要求,至少要要相同数量级的样本才行。要描述 99% 需要统计100个样本,要描述 99.9% 则至少要1000个样本,并以此类推。

再举一个作为翻译我的栗子
话说当年做的页游上线,在开服到了几百人(>500)的时候玩家会觉得比较卡,登陆服务器看了一下cpu和网络情况都不是很高(<30%),内存占也没啥问题。经过后来多方努力,发现是用户首次进入游戏时,为了数据安全,这时候初始化数据库的操作是同步的,而不是异步的。再加上dogse引擎的限定,主逻辑是跑在单线程的队列上,这就导致开服时主线程的阻塞会比较严重。每个玩家卡个200ms,同时有3个玩家进入,剩下的玩家自然会觉得卡了。

对于本书最重要的,而起是要重复说三遍的观点是:

测量,测量,测量

你要知道,如果没有准确的测量,在解决性能相关问题时,你只能按照自己的经验和感觉来判断那里有性能问题。这会存在2个问题:
首先:假设你的感觉是对的,找到了一个性能问题的地方,但你不知道当你修改了这里后,对性能提升了多少
其次:我也不可能告诉你那里经常犯错了。举个栗子(这个栗子我没看懂):在分析一个应用占用里很多非托管内存的问题,我们最初假设是认为在某处加载了一个很大的数据。随后安排开发人员做排查工作,通过禁止某些组件的加载,还调试了转储过程(dump)里堆的数据。结果让我们很吃惊,大部分内存的开销来自于组件(Assembly)加载,而不是我们之前所想的数据加载

如果没有工具做测量,那么性能优化就是没意义的。性能优化是一个连续的过程,你需要有自己的工具来对这个过程做记录。下面的章节将介绍一些常见的工具。恩大部分是免费的,有一款收费的,但是是vs专业版附带的,所以你懂的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值