2.3.4 并发性、扩展性和吞吐量

并发性也许是对性能指标最基本的认识。客户经常会提出一些表示应用程序必须支持的并发用户数的数量,但对其实际的需求却没有给予足够的考虑。

Scott Barber在他那篇精彩的文章《Get performance requirements right:Think like a user》中建议根据每小时的统计结果去计算并发数,这是一种比较理想和简便易行的做法。从性能测试工具的角度来说的并发,指的是通过软件生成的活动用户与并发访问应用程序的用户不一定相同。提供一个准确的并发级别,很大程度上要依赖于您的事务脚本设计,这将在后续的章节中讨论。

Scott还提到了另一个关键问题,即我们要得到的并发性和扩展性的能力目标。我把这理解为达到我们的扩展性目标以证明应用程序的能力足以交付商用,然而同样重要的是找出系统的容量有多少扩展空间。

在性能测试上,“并发”指的是以下两个截然不同的方面。

并发虚拟用户

从性能测试工具角度来看的活动虚拟用户数经常与在测试过程中真正访问应用程序的用户数有很大的不同。

并发应用程序用户

访问应用程序的并发虚拟用户数。我所说的“访问”指的是在测试过程中实际登录到系统。这个数字是衡量在某一时刻活动的虚拟用户的关键指标,它在很大程度上依赖于您如何设计性能测试事务(将在后续的章节中讨论)。现在您需要决定是否要录制登录和注销的过程(无论是否涉及)它将成为测试应用程序行为的一部分。如果您包含了“登录-注销”的过程,那么在测试执行过程中,对每一个虚拟用户来说都有一个重复注销、登录的动作,因此并不是真正与其他用户并发。获得确切的并发虚拟用户数的方法是调整一个事务循环的完成时间,以及设定两次事务循环之间的步进(或延迟)(参见2.8.1节)。这也被称为事务的吞吐量。

这种情况的一个例子是我最近参与的一个项目。客户希望测试1 000个并发用户,但是因为每个用户都在登录了系统后就完成操作,然后注销,因此在性能测试过程中的任一时刻,都没有超过200名用户在操作系统,尽管测试工具产生了1 000个活动用户。

解决的办法有:(1)增加每次事务循环执行的时间或持续时间以使用户保持更长的活动时间。(2)在两次事务执行的间隔设定足够的步进时间,以降低执行的频率。同时,重要的是确保在性能测试中获得的事务吞吐量能够准确地反映真实的应用程序行为。

如果您不想在事务的循环中包含“登录-注销”的过程,那么实现并发就变得容易得多,因为每个用户都成功地登录,并在性能测试持续过程中都保持活动的状态(出错的情况除外)。

并发的目标一种是从现行应用程序的数据中推算而来,另一种情况是,如果是新上线的系统,那么将基于预期的系统所有用户群数量的百分比去计算。

正如多数商业上的应用一样,80/20原则常常会起作用:在所有100个用户中,在工作日的任一时间内平均有20个用户在使用系统。也就是说,虽然每个应用程序会有所不同,但最好尽量争取测试高并发规模的情况,而不要低并发量的情况。同样重要的是,您要确定在系统部署后6个月、12个月、甚至18个月后的并发量。

您还必须预留出超过正常范围的使用高峰期的容量,举个例子,有一个为大型高校的学生和老师提供服务的应用程序,每一天的使用量都相对平衡,但在一年中有某个特定的时间,(比如在学生入学或考试成绩线上公布时)并发使用量有明显的增长。假如系统不能满足这种使用高峰,常见的错误情况是会降低系统的性能,还有更坏的情况是,将引起系统失效。

在某些情况下,性能测试的指标是吞吐量,而不是并发。这常常发生在被称作无状态的应用程序下,即没有传统的登录用户的概念。随意浏览一个Web站点的主页就属于这类情况,在这种情况下,访问人数和在给定时间段内的“点击数”,其重要性就超过并发访问网站的用户数。

另一个不同的地方是确定一套针对不同最终用户技能水平的吞吐量需求,有多少用户是专家级的,有多少用户是初级用户,在事务中各自应分配的百分比是多少?在多数情况下,10个专家级用户在给定的时间范围内,会比10个初级用户创建更多事务,假设他们是进行同样的操作。

技巧

一个好的经验法则是在您预计投入使用的并发数和吞吐量指标基础上增加10%,这样,您的测试就可以超出预期的要求。