话说性能测试,听上去比较复杂,实则,确实复杂。无论是从性能测试计划编写还是到测试执行、测试报告,没一个环节确实都不简单。这一篇主要是性能测试的准备工作描述,不涉及具体操作。还记得上一份工作的时候,我们组内开展了性能测试的培训,但是呢,老板要求我们必须,首先要学好linux,至少会装虚拟机,而且对没一个步骤都驾轻就熟,对linux的系统设计和实现要烂熟于心。我当时不以为然,这两者有什么联系呢?到今天我才明白,性能测试真的是一个包含软、硬件各个方面所有的知识,你必须要清楚的知道程序的设计、可能存在的漏洞、程序与硬件通信的过程、硬件指标的含义等等,这些还不是全部的,当然还包含性能测试的基础理论,如果这些你都掌握,那么你就可以轻松的入门性能测试了,否则还是门外汉,比如我。偶然的机会,我在公司的项目里接手了性能测试,下面我只是就我的经历,分享一些工作上的总结。
首先,要会梳理性能测试目标。一般一个项目上线之前,产品都会梳理功能上的需求,业务量的需求一并也会提到,但是他们提的不够明确,要么就是要多少用户量啦,响应的时间长短等。我们需要把这些业务上的需求转化为我们软件功能的性能需求上面去。而评价一款软件的性能包含哪些呢,业务上的包含TPS、响应时间、成功率、并发数,硬件指标上的包含cpu 内存 磁盘IO 网络请求等,了解了这些评价的指标,那么我需要把业务请求转化到这些目标上去。
我接触到需求有以下:
- XXX产品到年底期待50w用户量-->每月用户量是N个->根据以往算一个转化率->算出大概每个月会有多少请求,进而计算出多少并发请求
- 响应时间,也就是一个请求进来到返回的时间,这一点不需要转化
- 其他的,比如tps一般的要求是100上下,成功率100%,硬件上的指标大概维持正常水平即可
转化成为性能需求之后,我们就把这些列为性能测试的一个目标值,也就是把现实测试的结果与之对比,看看是否满足这个目标。
梳理了需求之后,我们接下来要设计性能测试计划,也就是测试用例,话说这部分是最让我头疼,因为性能测试是用于衡量线上的情况,但是我们不可能拿到线上的环境去执行,为此我们需要从各个角度去尽量的和线上持平。具体的,我这里列一下
- 数据库基础数据,这个要和线上目前或者未来某个时间段可能达到的数据量
- 请求参数模型,这个也要和目前线上的保持一致,也就是大概几成的用户会带这类参数,几成的用户会带其他的参数。这一块可以根据线上已经有的数据量去设计数据比例模型,也可以根据产品需求,如果是新项目,反正一切跟着业务场景来就行
- 部署结构。有些是通过中间系统去请求到我方系统,而我们在测试环境是否需要也要完全一致呢? 不一定,按照性能目标来指定。
比如我遇到的情况,我们的系统在线上提供dubbo服务接口,消费者系统通过请求这个接口来完成整个流程。但是,线上的这个消费者系统是持续部署的,也就是这个系统在启动后就一直在运行,并且与这个zookeeper保持了长连接,用户请求进来之后,可以立马通过zk去获取提供者的地址,从而快速得到响应。但是我们的测试工程呢,我们是在本地跑的,通过xml去和zk连接到服务提供者,由于我们的测试工程不是一个“服务” 也就是不是部署的,我们只是通过dubbo.xml的方式去临时获取一个连接,连接完成后即可释放,而并不是长连接的过程。这里的区别提现在哪儿呢,就是并发用户多,那么瞬间去与zk连接的消费者节点会变的很多,我的担忧是首先这个zk是否支持这么多的客户端去连接,还有就是是否会影响我们对响应时间的统计呢?关于前者,我查了一下,zk里有这么一个参数maxClientCnxns,来限制客户端请求数,官方是这样解释的
ZooKeeper关于maxClientCnxns参数的官方解释: 单个客户端与单台服务器之间的连接数的限制,是ip级别的,默认是60,如果设置为0,那么表明不作任何限制。请注意这个限制的使用范围,仅仅是单台客户端机器与单台ZK服务器之间的连接数限制,不是针对指定客户端IP,也不是ZK集群的连接数限制,也不是单台ZK对所有客户端的连接数限制。 maxClientCnxns Limits the number of concurrent connections (at the socket level) that a single client, identified by IP address, may make to a single member of the ZooKeeper ensemble. This is used to prevent certain classes of DoS attacks, including file descriptor exhaustion. The default is 60. Setting this to 0 entirely removes the limit on concurrent connections.
所以,很显然我们如果把测试工程放在同一台执行机去执行,是不会出现这个问题的,因为zk接收到的请求都来自于同一个IP,也就不会受到限制。对于第二个问题呢,我和对应的开发探讨了一下,他提出了我们这个接口的统计时间,可以通过数据库的时间差去统计,或者日志,这样我们就可以绕开与zk连接的时间差。特别是对于异步实现的接口,这个统计的tps和响应时间都是针对同步的,所以这个统计并没有意义。所以无论是通过什么样的形式,将用户的这个请求送达被测系统,我们的关注点只有【被测系统的性能】 没错,只要在请求到达被测系统的时候是一个并发的,那么就能构成我们的这个场景。特别是对于消息监听的这类接口,我们的测试类都是针对发送消息到队列的,这类tps统计根本是毫无意义的,因为服务处理的过程是个异步的过程,我们只要把消息送达被测系统,这种并发的请求,就能达到我们想要的测试场景。
性能测试需求、用例这两块是我认为在编写性能测试计划过程中最重要的两个部分,特别是目标的指定,一定要与项目相关人员进行评审。