当前位置: 首页 > 科技观察

性能测试需要注意的几点

时间:2023-03-21 23:27:58 科技观察

性能测试已经是一个常见的话题,不同的项目或多或少都会涉及到,但是每个人的体验肯定是不一样的。今天我想从以下几个方面分享一下我认为在性能测试中需要注意的点。一、性能测试的需求1、看似明确的需求当被问到性能测试的需求时,我们的客户有时会回答,“我们需要支持20000用户同时在线”,或者“每天10000用户同时访问”.这个网站”,更是“不知道,越多越好”。在这种情况下我们应该怎么办?当用户说“我们有10000个用户同时访问这个网站”的时候,似乎我们的需求就已经很“明确”了。真的很清楚吗?举个例子,这10000个用户在做什么?想象一下,可能有5,000个用户在浏览静态页面,2,000个创建表单,1,000个在做查询,并且......真正有压力的用户是谁?恐怕无法从同时访问该网站的10,000个用户中获取。之前做过一个项目,客户是一个机场,他们为用户提供免费的WiFi服务,但是在提供WiFi的同时,会在不同的页面播放广告。后台有广告管理系统,可以配置按优先级投放广告。这个涉及到一些复杂的算法,主要是广告的比例。当然,机场里有很多素材服务器,主要用来存放广告图片等等。当时用户给出的性能要求只有一句话,“我们每天有大约xxxxxx用户连接我们的WiFi”。那么如何进行性能测试呢?“有多少用户连接WiFi”其实只是最表面的现象。在连接到WiFi的同时,系统实际上做了很多事情。首先,当连接到WiFi时,它会访问分发服务器来决定播放哪些广告。其次,它会根据分发的广告,去素材服务器找到相应的资源,然后设法在数据库中记录广告访问的历史数据。能想到的一些最基本的后台操作就这些。每一个行为都可能成为瓶颈,需要慎重考虑。因此,在考虑性能需求时,需要知道其背后的逻辑是什么,同时需要分析用户活动,以确定系统的性能测试目标。2、历史数据“目前的性能需求不是很清楚,但是我们有原来的老系统,能不能帮我们看一下?”对于性能测试,如果有非常详细的历史数据,那将是一个非常宝贵的数据源,我们可以从中非常详细地分析用户行为。我们之前做过一个项目,对性能测试的需求基本都是从历史数据中获取的。我们对数据库进行了详细的分析,设计了性能测试用例,主要包括系统哪些服务有压力,压力有多大,用户量有多少等等。需要注意的是,如果对业务的理解不够深入,很容易造成场景设计的缺失,导致测试场景与实际场景出现偏差。比如分析某张表,发现系统有10000条插拔卡记录。有些人可能会直接开始写脚本来模拟一个用户每天进行10000次插卡和拔卡操作。殊不知,10000次插拔卡的操作是由4000个用户进行的……性能瓶颈很可能是在用户的管理上,而不是插拔卡带来的压力。所以建议大家在做历史数据分析的时候,尽量把场景分析的尽量全面,需要了解真实的业务,这样才能尽量减少分析错误。3、需求不明确“我们不知道需求是什么,你自己想办法。”这种情况一般出现在一个新项目,客户对上线后的用户量没有很好的了解。我们应该做什么?通常我们会对系统进行负载测试,就是给被测系统增加压力,直到性能指标(比如响应时间)超出预期或者某些资源几乎饱和。这时候,我们基本上就可以确定系统的瓶颈是什么,支持多大的吞吐量。经过一段时间的稳定性测试后,让系统保持一定的压力一段时间(比如一周),检查相应的性能指标。通过这种方式,我们可以告诉我们的用户系统当前支持多少用户访问和吞吐量。当然,现在说的是客户的要求。对于性能测试本身,我们也有一些明确的要求,也就是我们通常参考的指标。下面我将继续深入讨论这个问题。二、定义性能测试指标1.性能测试指标一般来说,我们会重点关注以下几个性能测试指标。响应时间:大家比较熟悉的是2-5-8原则(据统计,当网站慢一秒,就会流失十分之一的客户),一般来说,页面体验会在2到5秒,5到8秒页面体验会更好秒是可以接受的,但超过8秒基本很难接受。但有些项目也是例外,比如从海量数据中查询某些数据,或者生成报告(年报),这些可能不适合2-5-8原则,但前提是要做好客户管理。预计。吞吐量:指单位时间内客户端和服务端之间成功传输数据的数量并发量:同一批用户在客户端/服务端同时执行的操作数量资源占用:一般来说就是我们关注的资源有几个大块:内存、CPU、I/O和网络成功率:比如某些情况下API调用的成功率。一旦我们了解了我们需要关注的性能指标,我们就可以定义具体的性能测试指标。之前做过一个比较大的项目的性能测试。系统提供了很多服务,包括web服务和windows服务。基本上每个服务都单独部署在一个windowserver上,所有的服务都连接到同一个服务器上。一个数据库。由于此系统中没有网页,因此我们不考虑页面加载。我们首先从历史数据中了解到系统需要满足的并发量,对每个服务进行相应的压力测试,定义相应的性能测试指标。如下图所示:上图展示了web服务性能测试的指标和结果。这个结果是基于我们每秒有7个Post请求+3个Get请求的事实。性能指标包括我们单独对这个服务的内存监控、CPU监控、成功率监控,以及相应的原因分析。一般来说,对于内存和CPU的占用率,业界都有统一的标准,大家可以参考一下。由于我们的服务器有8GB内存和8核CPU,所以性能还是比较不错的。其他服务也类似。我们主要关注CPU、内存使用率和成功率。由于一开始就认为网络不是瓶颈(都在网络内),所以我们没有添加网络的相应指标。需要特别注意的数据库服务器不同于其他windows服务或web服务。对于DB服务器,我们需要特别注意I/O。数据库的瓶颈一般出现在I/O上。自定义指标在项目中,我们经常需要自定义一些其他的指标来查看某些特定的性能。例如:为了分析方便,我们在服务的一些关键方法上加上时间戳,方便排查问题。所以我们有一些指标。图1是某个方法的平均调用时间,图2是我们计算出的最慢调用方法的top10:一般来说,性能测试的指标可以从不同的方面来定义,比如响应时间、资源利用率、并发度,吞吐量,并发...3.如何排错我刚才在性能测试中提到了一些相应的指标。当我们发现有些指标不正常时,我们应该怎么办呢?什么?性能测试的指标往往是相互关联的。当遇到问题时,我们需要从这些指标的结果中找到真正的根本原因。这也是性能测试最重要的点之一。话不多说,我们来看几个例子:1.内存泄漏内存泄漏是性能测试中非常常见的一个点。可能存在内存泄漏。但是也有例外,比如用C#或者Java写的代码,因为内存回收是垃圾回收器本身的行为,不像C语言需要手动回收,所以即使一段时间内内存有上升趋势,如只要能恢复到原点,就没有内存泄漏。内存泄漏通常没有明显的症状。有一次客户抱怨服务中断了。该服务几个月前一直运行良好。怎么说就宕机了,然后我们做了很详细的系统日志。经过分析,发现是内存泄漏导致的。内存每天泄漏一点点,第三个月才出现服务崩溃,短期性能测试很难发现。下图是我们在做性能测试时发现的问题。很明显内存在一段时间内直接从200多MB增加到500多MB,内存泄漏的可能性很大。故障排除怎么样?我们使用了第三方工具ANTS,最终得到如下结果。很明显Sting类成为了最大的类,达到了211MB。是什么原因造成的?然后我们在工具Object的调用链上找到了String,最后发现代码中有一行判断错误,导致内存上升。2.API响应速度慢这是一个很常见的问题。光看现象,不知道系统哪里出了问题。可能是网络慢,内存瓶颈,或者是I/O的问题……怎么定位呢?首先我们还是找到对应的apiserver。通过性能测试报告,我们发现了以下问题。消息队列随时间增长得非常快。这个时候再看看APIserver本身的内存和内存。CPU没有问题,那么问题出在哪里呢?这时候很容易认为数据库有问题。比较两个不同的版本,发现我们改了数据库的存储过程,最后发现是存储的。进程的变化导致一个索引失效,最后反映在API上速度明显变慢了。添加索引后问题解决。一般来说,我们在修改数据库的时候一定要非常小心。很可能一个小的改动就会引起系统性能的急剧下降。对于性能测试,往往我们发现的问题都是表面问题,比如页面响应慢。但是,这可能是由多种原因引起的,需要深入分析。这也需要我们在做性能测试的时候收集足够的信息来支持分析,同时借助一些第三方工具来真正定位问题。4、关于数据库的性能测试,前面已经讲了很多,为什么一定要把数据库列表拿出来?我们来看看数据库服务器的特殊性:1.关于内存我们在测试服务器的内存的时候,如果是普通的APP服务器,我们在监控内存的时候,通常会有一个metric,比如,APP服务的内存使用量不能超过总量的百分比。对于整个服务器来说,通常也会有更多的内存剩余。而当我们去查看一个数据库服务器时,我们会发现可用内存量通常只有10M或者5M(取决于你的配置)...而当你将数据库的内存翻倍时,可用内存通常是它仍然只有10M左右。是什么原因?其实这跟数据库本身的工作原理有关系。数据库中io操作的基本单位是页。数据库在执行一条语句时,比如查询语句,会先从物理磁盘读取。将相应的页面加载到内存中,然后进行操作。因为数据库本身是不断读写的,各种数据都会缓存在数据库内存中。为了更快的读写,数据库会有算法来维护内存中的数据,保证数据尽可能的被保存。都是从内存中获取,而不是从物理内存中获取(内存访问速度是纳秒级,硬盘是微秒级)。所以一般情况下,数据库基本上会用完所有的内存。这就是数据库消耗内存的原因。这与其工作原理有关。只要系统能正常运行,其他内存都可以用来缓存数据。2、关于死锁死锁通常是指对资源的不当竞争,使双方无限期地等待,因为对方已经掌握了自己的资源。如下图所示:产生死锁的原因有很多,大部分是由于事务之间资源访问顺序的交替或者统一记录的并发修改引起的。数据库有不同的死锁策略。对于SQLServer来说,它会随机杀掉其中一个,至少可以保证另一个事务的正常运行;对于Oracle,它会评估两个事务并杀死它认为不那么重要的一个。因此,在数据层面,我们需要监控死锁的发生。一般来说,死锁是不可避免的,但是一旦频繁出现死锁,肯定会对业务造成影响。我们可以使用很多工具来监控死锁,比如SQLProfile。死锁的修正也是针对高并发的事务,尽量减少长度;将锁优先级调低(隔离级别低);以相同的顺序访问对象,并尽量避免用户在事务中交互。3.关于磁盘因为对于数据库来说,最重要的就是读写操作,所以磁盘对于数据库来说非常重要。现在很多数据库都是直接放在云盘上,云盘上的磁盘有自己的结构,但是很多年前,如果是我们自己的服务器,就得考虑磁盘阵列来保证效率和安全性磁盘。对于磁盘,我们通常以读写来衡量。有几个比较容易接受的指标可以用来衡量数据库磁盘的性能,比如AverageDiskqueuelength、datalifecycle等。另外值得一提的是数据库的碎片整理。当数据库读写一段时间后,由于频繁的数据插入,数据不会按顺序排列在磁盘上,所以我们在查找相关数据时,磁盘往往需要在不同的位置查找数据领域,导致性能下降。这时候我们就需要进行磁盘碎片整理来保证数据库的性能。但是这个作业本身占用的磁盘I/O比较多,所以尽量选择在系统不忙的时候。4.关于索引,相信索引是大家比较熟悉的话题。当数据量较小时,不建索引全表扫描性能尚可。但是,当数据量很大时,就必须使用索引。因此,指标是否合适是性能的关键。比如执行一条语句SELECTUserName,UserIDFROMUS.UserDetailWHEREUserName=“李四”这个执行与创建的索引有关。如果没有索引,则需要进行全表扫描,因此加载到内存中的页面数据量很大。那是相当多的。如果索引正确,它可能只需要将几个页面加载到内存中。我们在使用sqlprofile等工具跟踪一些长查询时,需要查看索引是否建立正确。这也是数据库优化中非常重要的一个方面。当然,索引虽然对读的性能有帮助,但是对写的性能是有影响的。我们还需要在适当的时候重新索引索引。原因是如果索引在物理存储上不连续,也会导致性能下降。这与磁盘碎片整理相同。一般来说,如果系统设计合理,最终瓶颈会出现在数据库上,而我们在做性能测试的时候,也需要了解数据库的特殊性,才能更好的进行性能测试。5、关于性能测试工具市面上那么多性能测试工具如何选择?性能测试工具其实有很多,比如Jmeter、Loadrunner、Galtling等,可以一一列举,要看很多方面:需要测试测试服务器的性能?还是前端的性能?还是移动端的表现?对于后端,您可以选择Jmeter、Loadrunner或Gatling。前端可以选择Fiddler、httpWatch等,移动端可以选择GT或者APT。项目成本,很多性能测试工具是收费的,也有很多是开源的,需要结合具体项目来考虑。我们也可以自己编写脚本来完成性能测试,只要能满足需要项目的要求即可。但是一般来说,使用现有的工具一般会产生比较好的测试报告,除非有一些特殊情况,比如某些协议的特殊性,或者一些很简单的场景等,一般来说还是建议使用现有的工具就可以了市场工具。在使用该工具时,尽量保证测试系统和测试脚本在同一个网络中,这样测试结果才有意义。写在最后总的来说,性能测试其实是一个非常复杂的过程。需要结合不同方面正确分析需求,根据需求设计合理的测试场景,定义性能测试指标,并在测试中选择合适的测试工具,结合多个测试结果进行分析排查。【本文为专栏作家“张艺”原创稿件,转载请联系原作者】点此阅读更多该作者好文