1. 背景技术

1、 软件性能测试方法: 采用软件开发技术, 编写自动执行的客户端代码,在每种需要测试的事务开始和结束的时候加入标记,按照测试设计执行测试代码,统计每个事务的响应时间和单位时间内业务的完成量(TPS)、事务成功率来衡量软件的性能。

2、 性能测试中的事务:从功能的角度理解是应用程序完成的功能单元、从性能测试代码内部来看,是一个请求和其对应的应答的集合 ,或者几组这样请求应答对的集合。

3、 无应答事务:由于业务的特殊性原因,客户端在请求过服务器以后,服务器应答客户端请求中告知“请求已收到”(或者服务器不做任何应答),之后不再继续通知客户端最终的处理结果的方式,称为无应答事务,见下面的uml序列图:

如果按照一般性的性能测试思路, 测试代码(客户端)只能把消息A发送前标记为A事务的开始,把“消息A已收到“的应答当做A事务的结束,由此得到的事务响应时间、TPS、成功率。 但事实上,A的结束应该是以外部系统收到处理结果为结束标志的,这个事务度量才能真正反映出被测试系统的处理性能。相比之下,一般的性能测试思路得到的结果只有部分的测试意义或者完全没有意义。

2. 技术方案描述

要解决的技术问题:

要解决的问题是如何在测试的代码中能够得到一个真实的无应答事务,之后的性能测试过程是相同的。

整体思路:

一般性性能测试方案中,测试代码是以模拟客户端为基础的, 在此思路下测试代码是无法定义出一个真实的无应答事务的,必须把客户端和在外部系统以某种方式联系起来,当外部系统得到请求A处理结果的时候能够以某种方式把结果通知到客户端。测试代码把请求A发送当作事务的开始,收到外部系统通知处理结果当作结束。

有几种设计方案可以完成目标,各有优缺点,可以在不同的场景下择优选用

方案一:在测试代码中,同时实现客户端和外部系统功能, 在运行时,通过事前的安排,请求A的发送和最后处理结果的通知都发生在同一个测试进程内,方便最后事务的计算。如图:

优点:在测试代码中完美的解决了事务定义的问题,方法简洁,事务定义没有引入其它必需添加的过程。

缺点:只能适用于某些特殊的情况,如果外部系统只能是1个或者有限的几个,那么这种方法不适合。

适用范围:

满足在一个进程内的1个或者多个性能测试模拟客户端的发送的无应答请求只能由某个特定的外部系统接收到。并且在测试方案中可以设计这个外部系统不会接收到其它测试进程内的无应答请求的结果。

例子:比如一个即时通信系统,一个即时通信客户端给另外一个客户端发送无应答消息,那么另外一个客户端就是外部系统。(即时通信的例子:飞信、QQ、MSN)

方案二:在测试过程,不会把外部系统真的纳入的测试里,通常会编写一个外部系统的模拟程序,称为挡板程序。

如果外部系统无法满足方案1的要求,可以采用方案2:每个测试客户端在启动后马上向挡板程序注册自己的位置,挡板程序查找注册信息,把请求处理结果返还给对应的测试进程。如以下图所示:

优点:解决了只有一个外部程序或只有一个外部程序地址的问题,实现方法简单直接,适合测试压力不是非常大的时候。

缺点:在事务A的过程中新增加了查询客户端位置信息,处理结果返回的过程,测试的准确度下降。(但这种影响是固定的、轻微的,实际的经验表明这种影响可以忽略)。在测试压力要求非常大、客户端、服务器测试机器非常多的情况、如果挡板程序只是一个,会有单点瓶颈。如果是多个情况下、多个挡板程序之间需要同步客户端的位置信息。 挡板程序的代码复杂度、可靠性、内存等都会是极大的挑战,这种情况下不建议采用这个方案。

方案三: 解决方案一、二无法解决的问题,在非常大的压力下、挡板程序可以是很多个、但是隐藏在负载均衡下面,使用一个、或者有限几个地址。这种情况下不再采用客户端注册的办法,而是设计一种客户端id与客户端所在进程ip地址的匹配原则,放入配置文件中,假如测试进程有50个,客户端id是数字或者可以转化成数字,对这样数字进行50取余数,同一个余数对应一个ip地址,这样就建立起来一个匹配原则。测试方和挡板程序都使用同一个规则完成整个测试过程,如下图:

优点:能够完成大压力情况下的性能测试,没有方案2中单点无法扩展的性能限制

缺点:整个测试过程需要复杂的设计和编码。与方案2相同,有事务不够准确的问题。

3. 技术方案的关键点和保护点

1、把客户端和在外部系统以某种方式联系起来,当外部系统得到请求A处理结果的时候能够以某种方式把结果通知到客户端。测试代码把请求A发送当作事务的开始,收到外部系统通知处理结果当作结束。

2、3种无应答事务度量的解决方案,以及其最佳的使用场景的确定方法。

3、客户端Id取余数与测试进程ip地址匹配建立起来的匹配原则