一是数据的准备。数据准备一定要关注数据的质量和数量,不要出现一些不符合业务逻辑的废数据,并且数据量要满足测试运行的需要。例如测试需要100组数据,但是实际只准备了50组,从而导致测试执行结果出现大的偏差。
二是测试执行。除了正确按照设计的要求去设置各种参数之外,还要关注系统是否存在功能问题,这往往成为性能测试的“盲点”。原则上性能测试之前必须确保功能测试已经完备,但是任何事情都不绝对,所以一般做性能测试之初,都会模拟一个用户去运行设计的场景,主要是确保“测试脚本正确性”、“在设计的场景中应用系统不存在功能上的问题”。很多性能测试过程往往因为功能问题导致性能测试失败,或者是测试延期的现象。
5.测试分析
测试分析的主要目的是要根据测试执行获取到的数据去判断造成系统出现瓶颈的位置,挖掘造成系统瓶颈的真正原因。这个过程是技术含量最高的一环,因为在测试执行过程获取到的数据会涉及到各个方面,在这个案例中就涵盖了网络方面的知识、系统方面的知识、应用方面的知识等,测试人员需要从这些繁杂的数据中挑出异常,系统越大越复杂在这个方面对测试人员要求会更高。但是这里面也有一些技巧:
在做测试分析时人员组成建议为: 开发人员、系统人员、测试人员共同组成。这样会在技术上填补个人技术上的不足。实际每个项目涉及到的技术都可能各有不同,对于个人来说不可能每样都精通。
反复比较一个类型的参数在不同时间的跳跃值,或者不同场景下同一个类型参数的变化。
在发现参数有异常变化时,不要轻易下结论,而是要尽量挖掘可能影响这个参数的其他参数值。在长期的测试过程中发现往往发现第一个所谓的瓶颈都是因为其他因素造成的。
在测试分析时使用较多的一种方式是排除法,根据开始获取到的信息大概能将问题定位在某一层面上。但具体在什么地方,就可以采取排除的方法去定位。
尽量使用一些比较成熟的工具协助分析工作,这样将大大减轻工作负担。
在确定出真正的性能瓶颈时,可以做一些小的测试模型去做验证,确定分析的正确性。
在本案例中,在测试结果经过各种比对之后,最后确定是数据库层上出现问题。但是问题究竟出现什么地方呢?笔者在分析过程中采用了许多排除法,比如更新索引的统计值、将数据库中的表从页级锁改为行级锁等,但是都效果甚微。
所以,我们回到上面看与数据库层相关的需求:
1. 因为业务需要,需要使用很多模糊查询。此类操作会进行表扫描。为了防止脏读,会向数据库申请表级意向锁。
2. 因为客户关系复杂,所以数据库设计的时候,存在多表关联。
3. 在应用开发时,我们使用了Hiberate这个组件,这些组件对于开发人员来说是一个黑盒,而且存在一些局限性: 在更新记录时会同步更新所有相关联的表,即使关联表不需要更新; 同步更新的记录操作会涵盖一个事物处理过程中,会产生大事务操作; 无法利用SQL优化技术去优化他所产生出来的SQL语句。
研究之后发现: 在进行模糊查询与大客户信息录入与修改的操作时,由hiberate这个组件产生的大事务SQL导致了数据库的互锁,是系统瓶颈所在。为了验证这一判断的正确性,笔者做了一个小的模型去验证。
假设库中有A、B、C三张表,现在有三个虚拟用户同时在上面进行操作: 用户Vuser1需要查询客户信息,他只知道客户的姓氏,所以他采取了模糊查询; 用户Vuser2正在修改一个客户信息,正准备保存; 用户Vuser3正在查询客户办公信息,也需要模糊查询。
Vuser1操作先得到执行,在表扫描中出现表级意向锁; 此时Vuser2进来需要修改A、B、C三张表对应记录,并成功的锁定了B、C两张表对应的行(因为是行级锁),然后进行了修改,但是无法修改表A,所以Vuser2此时等待Vuser1释放锁; 此时Vuser3进来了,需要查询C表,因为Vuser2并没有释放锁,此时Vuser3也处在等待状态。验证显示,在出现大数量的操作并且在多用户的操作下,此瓶颈将不断地暴露出来。
6.系统调优与验证
将获取的分析数据交付到开发组进行调优,经过调优后一般都需要再次进行验证,验证主要关注调优后的结果是否解决了所发现的系统性能瓶颈和是否产生了新的性能瓶颈。这方面的工作主要由开发人员来完成。在本案例中,去掉了Hiberate组件,改为由应用自身控制,尽量减少了大事物的出现概率,并同业务部门商议,降低了模糊查询操作的次数。在后来再做“性能评测”时确认系统达到了预期目标。
原文转自:http://www.uml.org.cn/Test/200809046.asp