发布 Web 应用程序时避免瓶颈的实际负载测试技巧

发表于:2008-05-16来源:作者:点击数: 标签:webWebWEB负载瓶颈
摘要 负载测试应该是每项 Web 开发 工作的一部分,并且应在开发过程的早期进行。然而,如果您认为可以利用开发环境进行负载测试,那么当您发布应用程序时多少会感到惊讶。在本文中,作者将对规划负载测试工作、考虑使用哪些计算机、模拟用户的数量、适用的工

摘要 负载测试应该是每项 Web 开发工作的一部分,并且应在开发过程的早期进行。然而,如果您认为可以利用开发环境进行负载测试,那么当您发布应用程序时多少会感到惊讶。在本文中,作者将对规划负载测试工作、考虑使用哪些计算机、模拟用户的数量、适用的工具以及如何解释结果这一过程进行概述。

让我们设想以下场景。您即将结束为期 6 个月的对某项复杂的 Internet 应用程序或 Web 服务的开发工作,并且已准备对其进行部署。开发团队小心翼翼地就松散耦合的 n 层 Web 应用程序进行了设计。从工作的第一天开始,所有可伸缩、稳定的和高性能的应用程序所必需的要素就已悉数构建到系统的体系结构之中。质量保证团队已对系统进行了彻底地测试、解决掉了大部分的严重错误并仔细考虑了那些待发现的剩余错误。因此,您的开发工作应该进行得相当顺利,对吗?请再想一下。

您已将负载测试作为开发工作的一部分进行实施了吗?如果没有,那么您应接受这样的事实:即,在复杂的设计当中,您将需要就某些地方的性能、可伸缩性和可靠性方面予以关注。瓶颈是系统中阻碍正常通信量流量的元素。尽管良好的设计对于构建成功的 Web 应用程序而言至关重要,但是经验告诉我们,大部分这些种类的错误只能在系统处于较大负载的情况下才会被发现。这些是您作为单个用户在开发过程期间,通过测试系统无法发现的问题。尽早地实施负载测试计划有助于确保将在开发时出现的意外情况降至最低限度。

在本文中,我们将介绍基于实际经验的测试方法,但这并非抛开传统的负载测试策略。由于带领过众多的负载测试团队,我们汲取了一些教训,它们可能会对您有所帮助。

我们将讨论较早开始测试工作的优点,并概述设置测试环境的注意事项。我们将帮助您确定适于自己的实现的度量标准,并介绍一些实施这些度量标准的工具。此外,我们将向您说明,为什么“我的站点能同时处理 x 名用户吗?”这样的问题太过含糊而无法精确回答。最后,我们将讨论一些针对您的特定需要选择适当的负载测试工具的重要注意事项,并对跟踪测试结果提出一些建议。

我们将使用术语“负载测试”来描述性能、可伸缩性和可靠性测试。人们往往过于频繁地使用术语“可伸缩性测试”来描述上述这三项,而您的团队所做的很可能不仅限于此。图 1 描述了这些目标。

尽早开始

您应在设计阶段就开始规划负载测试工作。根据我们的经验,建议您采取“无惊讶”方法来进行开发工作。工作时始终抱着会发现问题的想法。分布式 Web 应用程序和 Web 服务的体系结构日趋复杂,使得潜在问题成为应用程序设计中的固有现象。

最近,我们在复杂的 n 层 Web 体系结构的开发阶段中,进行的负载测试效果不错。但我们对其中的两个问题估计不足。第一,我们低估了测试开始后将会发现的问题数量。我们的第一次测试运行在只处理了 2 名用户和 100 份定单后就告失败了。第二,我们低估了设置测试环境所需要的时间。幸运的是,由于我们开始规划测试足够早,从而有时间解决在部署日期之前发现的问题,或将问题降到最少。通过密切关注设计,成功地解决最初的几个问题后,系统的可伸缩性很快就得到了提高。

通过定义测试环境,您就可以开始规划测试工作。根据测试工作的规模,这可能是很重要的任务。

QC>

定义环境

在定义测试环境的过程中,第一个任务就是估计需要何种工作。我们用于资源成本的一条通用指南是,将实现时间的 15% 至 20% 用于测试,其中的大约三分之一用于负载测试。

重要的是创建单独的测试环境,该环境应与生产环境类似。如果计算机的配置、速度和设置均不相同,那么要推断出生产环境中的性能几乎是不可能。换言之,对于诸如“向系统添加更多硬件是否能提高可伸缩性”这样的问题,您能给出确定回答,但是对于“在生产环境中一台 Web 服务器能处理多少用户?”之类的问题,您却无法准确回答。您的主要任务之一就是降低不确定性,并通过结论性的证据来回答问题。如果没有类似的硬件,在迫不得已的情况下,您充其量也只能根据经验进行猜测。

面对将生产用计算机用于负载测试环境的成本,您可能会畏缩不前。但请您考虑考虑在生产环境中查找与硬件相关的问题所需的成本,以及精确预测单台 Web 服务器能处理的负载的价值。诸如处理器速度和可用的 RAM 之类的变量会影响可用系统资源,并随之可能更改可伸缩性问题表明它们自身的方式。在实验室中,环境变量是不可抗拒的因素。该种变量数量太多,而您无法确定问题的根源。如果不可能使用单独的环境,那么请考虑加速生产硬件购买以用于负载测试实验室中。一旦部署了系统,实验室设备就还可以用作生产设备的备用品。另一个好处是,用不着等到发布之日前,您就能消除系统缺陷

关于为何您不应使用开发环境进行测试,有几点原因。有关详细信息,请参阅提要栏“Don't Use Your Dev Environment for Load Testing”。对于质量保证团队所使用的系统测试环境,情况亦是如此。这适用于想要跟踪似乎与系统负载无关的功能错误的单个用户测试。这种测试对系统测试环境中使用的硬件类型放宽了限制。它从开发团队接收的软件更新也更频繁。在负载测试中,应只安装影响系统性能的版本,以将修改负载脚本的耗时缩至最短。

除了可伸缩性实验室运转所必需的资源以外,负载测试工作是否能成功还取决于组织中的其他角色。图 2 角色摘要。

实验室以外最重要的角色是具有很大权限的数据库管理员 (DBA),这个事实无需我们过分强调。可伸缩性问题最可能的根源就在于数据库、数据访问策略(例如,存储过程、预处理语句或内联 SQL)或数据访问技术(例如,ADO、ODBC 等等)。DBA 能够帮助识别和解决与数据库相关的问题,例如建立索引成本过高、过度锁定以及事务超时。理想情况是,您应有一位专门的称职的 DBA 来作为负载测试工作中关键点的全职资源。

我们还建议您让开发团队中的成员轮流负责测试实验室,以便每名团队成员都能参与到这项测试工作中。如果这样做,您将取得极佳的交叉培训的效果,并持续地向实验室提供最新的理念。

定义测试策略

到目前为止,您肯定参加过这样的会议,客户倚靠在宽大的会议桌上,问您:“这个系统能处理上千个用户吗?”传统的负载测试方法要求您编写脚本并执行测试,以试图给出此问题的精确答案。对于这种测试,您需要定义“处理”的含义以及 1000 名典型用户在站点活动时的情形。您需要定义测试用例以代表各种用户活动:例如,购买股票或注册新的帐户。接下来,您必须估计用户在这些测试用例上的分布。对以下数据进行假设,即模拟真实用户与应用程序交互时,需要多长的思考时间(或等待时间)。因此,负载测试期间活动的可从某个方面大致反映出同样数量的真实用户在站点活动时的情形。

这种方法有几个不足之处。首先,其结果不会比您做的假设更好。显然,不正确的假设将使结果出现偏差。

其次,估计真实用户需要大量客户端硬件。如果对每名虚拟用户给定需要的处理能力和内存量,则典型的客户端计算机可以处理大约 200 名虚拟用户。因此,对 2000 名用户并发处理级别的测试需要 10 台客户端计算机 — 这是一笔重大投资。测试使用 HTTPS 的站点将需要多得多的客户端硬件。

最终,此方法难以向您的开发团队提供以操作为导向的信息。当某处出现故障时,常常难以再现该问题。

作为备选方案,我们建议您围绕以下这些关键问题设计测试用例:

系统瓶颈在哪里?系统能同步处理多少个并发请求?

在响应时间变得不可接受之前,一台机器能处理多少名不同步的超级用户?

添加额外的硬件时,结果是线形增长的吗?

有任何稳定性问题会妨碍站点运行于生产环境中吗?

此方法将使用开发团队(此开发团队参与可能出现问题的领域)提供的附加信息。请关注这些领域。对于上一个示例,其瓶颈可能出在定单提交领域。从这里您可以派生出更具体的问题,例如“提交流程可以同时处理多少个请求?”攻击这些特定领域是最快且成本最小的方法,用来向开发团队提供以操作为导向的信息,以便他们能改进系统。在使用这种方法的同时,我们推荐您记住遵循以下建议。

关注负载测试正如我们已提到的那样,首先要做的是构建导致潜在瓶颈和稳定性问题的脚本。这种“数据第一,假设第二”的方法使您能够从应用程序收集原始数据,然后根据假设确定更高级别的结果。不用担心为识别低风险站点的脚本编写问题。例如,为站点的帮助领域或只读文档领域编写脚本不大可能出现系统瓶颈。

同步请求使用同步请求攻击瓶颈。此处的这个主意是模拟最坏的情况:即,站点上的用户精确地在同一时间攻击瓶颈。通过使用户同步,您可以重复进行此测试。如果不同步结果,则难以再现故障情况。可以使用同步点做到这一点,同步点是大多数较健壮(成本也较高)的测试工具中提供的一项功能。同步点迫使每名虚拟用户一直等到剩余的用户到达脚本中定义的点后,才能开始下一请求。它允许您精确并重复地确定站点的潜在瓶颈区域能处理的并发用户数。例如,下限可以是 7 名并发同步用户。

创建循环测试用例脚本使测试用例循环。在另一种方法中,每次测试用例迭代前后,站点应处于相同状态。这允许您长时间地重复运行测试用例。

使用超级用户最后,使用我们所称的超级用户。正如前面所提到的,超级用户运行时思考时间设置为零。请记住,思考时间假设是用于常规测试中,以使虚拟用户模拟真实用户。但是,如果将虚拟用户思考时间减半,则服务器的实际负载将加倍。在另一种方法中,服务器真正关心的与负载有关的变量是每秒的请求数。虚拟用户的数量及其思考时间结合起来生成该负载。

让我们进行一些数学运算以使此概念更清晰。下面的公式计算访问站点的真实用户生成的负载(请求数/秒):


例如,某个站点有 100 名并发用户,假设下载时间为 10 秒,思考时间为 30 秒,则每秒将生成 2.5 页。如果我们假设每页 3 个请求,则在 Web 服务器上将转化为每秒 7.5 个请求。

以超级用户运行测试时,观察每秒请求数,并与刚刚计算的值比较。根据我们的经验,真实用户数与超级用户数的比例通常约为 15:1。对于同一个示例,这意味着 (100/15) 名超级用户将生成与 100 名普通用户相同的负载。再举一个例子,假设在 10 名超级用户之后响应时间变得不可接受。请注意转换回真实用户数的该点每秒请求数。现在您可以进行任何希望的思考时间假设,甚至可以更改它而无需重新运行测试。在几天的测试之后,您将能根据直觉从超级用户数转换成真实用户数。此方法允许您保持用户数可控,减少所需的客户端硬件数量,并包含负载测试软件的成本。

这些超级用户测试用例对于多机测试很有用。要测试站点的可伸缩性,可添加第二台 Web 服务器和一个负载平衡器,并重复超级用户测试。理想情况下,在看见相同的相应次数之前,您将能加倍超级用户数量。

要回答稳定性问题,可运行测试,以在延长的时间段内维持合理数量的并发且未同步超级用户。我们在上一个项目中熬了很多个通宵,甚至 24 小时昼夜不停,但持续时间与应用程序有关。我们称之为“内置”测试。一旦您已采取步骤识别并潜在地解决了找到的瓶颈,则重复同步点测试,看下限是否有所增长。然后用所支持的新的并发用户数重新运行“内置”测试。以努力提高此数字为目标重复该循环,直到达到质量条。

但是有多少用户呢?

尽管此方法向开发团队提供了有价值的信息,但它使得您更难于回答会议室的问题。不过,您可以近似地估计答案。例如,假设站点的最坏情况瓶颈显示,每台计算机多于 20 名超级用户的情况下,响应时间超过 10 秒。根据您从我们建议的公式计算的结果,近似地估计有 300 名真实用户(20 名超级用户 × 15 名真实用户)。此时,您可以做出与常规用例中相同的假设。通常情况下,有百分之多少的用户正在使用站点的此领域?假设预期 50% 的用户正在使用此领域,而其他领域,例如文档或数据库读取,用户比例则没有这么大。这意味着具有一台 Web 服务器的系统将处理大约 600 名用户。

到目前为止,我们已讨论了在能明确地指向站点的一个瓶颈领域的情况下该如何做,但如果影响性能的领域不止一个时您又应如何做呢?答案是创建单独查看各个领域的测试脚本。首先孤立地运行这些脚本,然后一起运行。再比较结果,看站点的一个领域对另一个领域的影响有多大。

了解度量标准

下一步是清楚地定义度量标准。度量标准的例子包括:每分钟处理的定单数,或者执行对 ASP 页面的请求所需要的毫秒数。度量标准允许您量化每次测试运行之间进行更改的结果。它们提供了与为您的 Web 应用程序定义的标准之间的一种比较。

为了确定需要跟踪的度量标准,需要采取一系列步骤。您需要定义待回答的问题,为每个问题定义质量条,然后确定将测试结果与质量条进行比较所必需的度量标准。

第一步很直接。例如,您可能想要了解签出响应时间。请记住列出那些与测试策略相关的问题,而避免组织您无法测试的模糊问题。

下一步是为每个问题定义质量条。让我们以典型的定单提交流程为例。我们可能决定站点在峰值负载期间每分钟必须处理 10 份定单,一名用户等到请求执行的时间不应超过 30 秒。为了建立这样一个标准,您可能会注意许多不同的源。首先咨询业界人士,了解系统性能的可接受级别。将历史数据带到这些会议上将有助于讨论,并常常可用来管理预期情况。如果在生产环境中已存在某个版本,则可以从当前站点活动和增加的通信量的短期投影收集数据,或通过查询现有数据库的活动趋势来收集数据。

有了一份问题列表和每个问题的质量标准后,您现在就需要确定使用哪个度量标准。根据上一个例子,每分钟定单数和给定测试中的定单数将是良好的高级度量标准,这些标准可作为站点是否满足质量条要求的指示器。当您想要在测试过程中更新这些度量标准时,应报告给管理层。

较低级的度量标准衡量性能并帮助您解决系统瓶颈和稳定性问题,或将这类瓶颈和问题减到最少。增加性能也许会对高级度量标准产生直接影响。例如,减少特定活动的事务时间可能导致每分钟定单数的增加。

大多数测试工具允许您在个别页上或一组页上设置定时器,并提供运行测试用例的平均时间。两种度量标准均允许您将高级度量标准用于一次又一次测试运行,但它们均不能帮助您深入了解到底是什么需要改进。

对此 Windows 性能计数器很有用。例如,您可以监视 dllhost 进程的 Process:Private Bytes,以检测服务器软件包中的内存泄漏。有关各个Microsoft Internet 信息服务 (IIS) 计数器的适合且详细的描述,可从 windows2000/techinfo/administration/web/tuning.asp" target=_blank>The Art and Science of Web Server Tuning with Internet Information Services 5.0 获取,而图 3 描述了用于负载测试的主要计数器以及要注意的趋势。

但是,性能计数器只在识别问题症状时有用,对识别问题原因无用。如果您的系统在 20 名并发用户时中断,则 Active Server Pages:Requests Timed Out 计数器可以真正确认,至少一名用户已超时,但要确定超时的原因却如同大海捞针。这是因为性能计数器数据主要提供操作系统和网络级别的信息。要成功找到问题的原因,需要访问应用层的数据。此任务的关键是,构建分布式日志记录系统,以检索并集中存储来自应用程序中的错误和性能数据。这允许您立刻了解系统是否正在工作。如果系统没有工作,则您就拥有了找到问题领域所必需的信息。

解释度量标准

配置完所有这些度量标准之后,现在您就可以访问大量数据。因此,您将如何以有效率的方式来理解数据?我们将针对解释性能计数器数据讨论三个选项:性能监视器、Perfcol 以及与负载测试工具集成的性能数据。

Windows 2000 中的性能监视器允许您以图形的方式显示各个计数器的进度。一个有用的功能是能够在日志文件中捕获读数,从而允许您在测试运行一完成就以可视的方式检查整个测试运行。图 4 说明了在线订购应用程序上的站点活动如何能在性能监视器中得到解释。

沿着与性能监视器同一条线,Windows DNA Performance Kit Beta 包含一个称为 Perfcol 的工具。此工具的用途与性能监视器类似,不同之处在于该工具将取样数据存储在数据库中,而不是写入文件。

一些负载测试工具,例如 Microsoft Application Center Test (ACT) 和来自 Empirix 的 e-TEST 套件,均包含内置的性能计数器功能,它们能在测试的运行持续期间记录度量值。然后计数器数据会写入数据库以供以后访问。ACT 包含在 Visual Studio .NET 中,它集成了性能监视器计数器,允许所有数据均存储在单个资源库中。

不管负载测试工具是否集成某种形式的性能计数器监视,您也许均会发现仍需要诸如性能监视器之类的工具的支持,尤其是如果产生负载的服务器没有适当的安全访问权来监视应用程序服务器时,这种情况在环境包含防火墙时会频繁发生。

无论选择何种监视工具,关键在于存储每次测试运行的度量标准以供将来评估。转回到过去的数据对于理解系统如何响应所作的更改很关键。

对于日志记录系统生成的应用级数据,我们建议构建一个查看器,该查看器使您能够立即访问一个位置内的错误和性能信息。考虑到它所代替的操作是每次要求反馈时在命令行生成 SQL 查询,因此这项工作还是值得的。

选择适当的负载测试工具

要实施此项测试策略,您需要能选择合适的负载测试工具。可用负载测试工具的完整评估已超出本文的讨论范围,但我们仍希望帮助您确定一些在选择适当的工具时的选项和注意事项。

第一个选项是考虑诸如 Windows Application Stress Tool (WAST) 这样的免费工具。另一方面,您还可以选用更为灵活的工具,例如 ACT 或 Empirix 的 e-TEST 套件。图 5 显示的是 e-Load 的界面,它是 e-TEST 套件的负载生成部分。

这些工具之间有一些明显的功能差别。WAST 对于不太复杂的较小站点是不错的工具。您可以轻松地测试站点上的两三个关键页面,并很好地了解响应率是多少。但是,仅仅一个能测试多页面站点的隔离测试工具还是不够的。而且,WAST 中没有提供对于测试复杂站点必需的几个重要功能(以及本文中一些建议的实现)。要使用 WAST 获得复杂结果,需要您自定义应用程序,以便对其进行负载测试,这显然是您所不希望的。

要执行我们针对复杂站点所建议的测试,诸如 ACT 或 e-TEST 套件之类的更健壮的测试工具将更有效。如果您在 .NET 中进行开发,那么 ACT 将集成到整个开发周期中。但是,这需要 ACT 对象模型的编程技巧和知识,以生成强大的测试脚本。如果您决定使用诸如 e-TEST 之类的工具,则需要支付一笔许可费。


图 6 ACT 结果界面

质量工具必须不仅仅能有效地测试站点,还能以有用的方式报告测试结果。ACT 和 e-TEST 均提供详细的报告环境,允许您在需要的时候将结果绘制成图像。ACT 结果界面显示在图 6 中。图 7 提供了公共特性的摘要,以及必须提供的每种工具类型的描述。

如果您确定更健壮的工具的确有必要,请不要低估启动和运行必需耗费的时间。有些工具会宣称只需几个小时就能编写开始测试所必需的脚本。如果您先前就有使用该工具或类似的负载测试工具的经验,可能的确如此。但请做好耗费几天甚至几周进行准备工作的思想准备,所需的时间取决于站点的复杂程度。我们的第一个测试用例耗费了大约三周时间才启动和运行。您可能会发现,尽管学习了一遍样本教程,但仍有一些诀窍只能从实践中学到,而且要经常致电支持热线。耗费几个小时学习工具,其效果可能远胜于正规的训练或聘请有经验的顾问。而且,如果在开发阶段的晚期开始测试工作,您将承担不起浪费时间的损失,在这种情况下强烈建议使用以上两项资源中的一项或全部。

了解历史情况


您在一天之内甚至一周之内的测试数可能会变化。如果在调整 Web 服务器,则您可能决定运行一系列每小时一次的测试。如果您的目标在于测试应用程序的稳定性,则可能会整晚运行测试。不管是哪种方式,除非您保存一份文档历史记录,否则要跟踪从一个测试到下一个测试的变量和进度将会很难。有一点至关重要,即您能轻松地确定已进行了哪些测试、找到了什么以及接下来应测试什么。

至少应记录运行的开始和结束时间、测试中的虚拟用户量以及一份描述测试目标和更改内容的开始说明。以一份描述测试结果的结束说明完成运行。

小结

要成功部署复杂的 Web 应用程序,您必须首先采用超出系统测试范围的“无惊讶”测试方法。负载测试由可伸缩性测试、性能测试稳定性测试组成,它是发现体系结构中主要内在问题的唯一方法。为了达到此目的,您需要一个单独的生产环境,环境中有类似的生产硬件、健壮的负载测试工具以及组织中若干人员的协作。

适当的度量标准可提供确定系统是否满足质量条的方法。当然,对于可伸缩性实验室团队而言,最有价值的是分布式日志记录系统捕获到的错误和性能数据,因为它能提供应用级的信息。

通过使用本文中讨论的建议并确保记录工作情况,可以很好地保证在计划的日期内顺利地进行部署。

原文转自:http://www.ltesting.net