65.9K
CodeProject 正在变化。 阅读更多。
Home

Visual Studio 2008 Load Test Gotchas

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.50/5 (5投票s)

2010年9月16日

CPOL

17分钟阅读

viewsIcon

51764

Visual Studio 2008 中的负载测试功能,通过 Team Suite 扩展或 Visual Studio Tester Edition 提供。

目录

致谢

在我开始解释 Visual Studio 2008 负载测试的经验之前,我想特别感谢 Edgars Ozolins,没有他,这篇文章可能还躺在我的硬盘上,未完成。他不仅“忽悠”我完成了这篇文章,还修正了我所有的拼写错误。所以,如果你仍然发现一个错误,那说明在他修改之后,我又尝试添加了新的内容。谢谢你,Edgars。

引言

今天,我想谈谈 Visual Studio 2008 中通过 Team Suite 扩展(或 Visual Studio Tester Edition)提供的负载测试功能。Microsoft Load Testing Framework 允许录制用户操作(Web 测试),然后在指定的时间间隔内多次执行它们,同时收集测试结果(负载测试)。换句话说,负载测试(也称为压力测试)就是重复执行 Web 测试以模拟多用户负载。

开始负载测试相对容易,但同时,要正确地进行负载测试可能变得极具挑战性。我倾向于认为原因在于负载测试的实现。因为负载测试收集的数据不包含每一个单独的请求(只有平均值、最大值、最小值和其他聚合数据),所以你必须一开始就正确地设置你的负载测试。

设置

在继续之前,我们需要一个可以运行测试的站点。本文将使用一个简单的包含三个按钮的站点。这个站点的特殊之处在于它只有一个页面,因此默认情况下,VS 会计算点击任何按钮时的通用平均值。在某些情况下,这还可以,但你很快就会意识到,在某些情况下,你可能想要分析同一页面上不同功能在压力下的表现。在我们的站点中,当用户点击这三个按钮之一时,我们将通过让线程休眠不同的时间来模拟不同的功能。

  • 3 秒 – 点击第一个按钮时(完全回发)
  • 0.3 秒 – 点击第二个按钮时(AJAX 回发)
  • 9 + 3 秒 – 点击最后一个按钮时,用户将等待 9 秒获取 HTTP 重定向代码,然后等待另外 3 秒获取重定向页面的内容。

图 1:要测试的网页

Web 测试

录制 Web 测试

在创建负载测试之前,你应该至少有一个可以重复执行的 Web 测试(或单元测试)。通过右键单击项目并选择“添加 -> Web 测试…”来创建一个。这样做将强制打开“Web Test Recorder”。当点击录制按钮时,用户执行的所有操作都会被录制下来,以创建新的 Web 测试。

让我们创建一个 Web 测试,用户先点击第一个按钮(休眠 3 秒),然后点击第二个按钮(休眠 0.3 秒)。参见图 2。

2:设置 Web 测试

从测试中移除初始页面打开和两个 favicon.ico 请求(由 VS2008 自动完成),只留下要测试的功能。你也可以移除“Response URL”验证规则,因为它不需要。

接下来,我们必须清理掉我们通过从 Web 测试中移除录制的请求而产生的混乱。默认情况下,Visual Studio 会尝试使用上下文变量(看起来像这样 {{$Variable}})中的数据来重用 POST 参数值。更准确地说,Visual Studio 会在接收到的 HTML 中找到所有隐藏变量,并以 HIDDENX 为前缀创建上下文变量(例如,{{$HIDDEN1._VIEWSTATE}}),然后将后续请求的 POST 变量绑定到一个创建的上下文变量。

由于我们移除了第一个请求,第二个请求中的绑定不再有效,我们必须回退到使用录制的值。要做到这一点,请遍历“Form Post Parameters”中的每个参数,并取消绑定值,如图 3 所示。

图 3:处理表单 POST 参数

这是我们剩下的内容。

image

图 4:清理过的 Web 测试

运行 Web 测试

现在该运行我们的 Web 测试以查看它是否正常工作了。要运行测试,请单击 Web 测试窗口中的“播放”按钮。

图 5:Web 测试成功运行

你可以看到所有请求旁边都有一个绿色的勾,并且所有测试都显示“Passed”状态。如果我们有一个失败的请求,那就意味着服务器返回了一个 5XX 状态码,或者与之关联的一个验证器失败了。值得注意的是,测试在某个请求失败时可以停止或继续,但在两种情况下,整个测试的结果都将是“Failed”。

让我们暂时添加一个验证规则,看看失败的样子。

图 6:设置验证规则

我们还通过启用具有匹配名称的 Web 测试属性,让 Web 测试在错误时停止。

图 7:设置 Web 测试属性

现在运行测试将会失败,你可以在“Details”选项卡中看到原因。另外请注意,跟随失败请求的请求根本没有运行。

图 8:Web 测试在验证规则上失败

负载测试

创建负载测试

现在让我们通过右键单击项目并选择“添加 -> Web 测试…”来创建一个简单的负载测试。设置向导将打开,但我们暂时跳过除“Test mix”之外的所有步骤。

图 9:设置测试混合

在“Test Mix”步骤中,你需要将我们的 Web 测试添加到 Web 测试列表中,这些测试将在进行负载测试时重复执行。

如果你没有修改其他步骤中的数据,你应该已经创建了一个负载测试,该测试将模拟 25 个用户点击第一个按钮然后点击第二个按钮,持续 10 分钟。

我们还将在此示例中禁用缓存。要禁用页面缓存,必须将新用户百分比设置为 100%(参见图 10:在负载测试中禁用缓存)。这将使每个模拟用户都像第一次访问页面一样,意味着他每次都需要下载 ScriptResource.axdWebResource.axd

图 10:在负载测试中禁用缓存

运行负载测试

最后,我们有了一个可用的负载测试,我们可以运行它,但在运行之前,让我们考虑一下在完美条件下我们应该获得什么数据。假设 IIS 配置最优(在我的情况下,最简单的方法是增加应用程序池设置中的“Maximum Worker Processes”),并且因为我们的测试包含两个操作,我们应该得到一个平均响应时间,等于 (3s + 0.3s) / 2 = 1.65s。

这是实际测试结果。参见图 11。

图 11:负载测试结果

Average Response Time (Total) – 显示每个响应的平均响应时间。正如你所记得的,整个测试总共进行了 5 次请求:Default.aspx(3s)、Default.aspx (0.3s)、WebResource.axd,以及 ScriptResource.axd(调用了两次)。

Average Page Time (Total) – 显示执行 Web 测试中的一个操作所需的平均时间。在我们的测试中,有两个操作:点击 3s 按钮(导致下载 WebResource.axd 和 2xScriptResource.axd,因此时间略多于 3 秒),以及点击 0.3s 按钮。

Average Response Time (default.aspx) – 下载 default.aspx 所需的平均时间。不包括其他任何请求。

Average Response Time (WebResource.aspx) – 下载 WebResource.aspx 所需的平均时间。

Average Response Time (ScriptResponse.aspx) – 下载 ScriptResource.aspx 所需的平均时间。

正如你所见,“Average Response Time”的平均值略大于 1.65s。这意味着,尽管这个数字非常接近,但它并没有显示平均执行操作所需的时间。这个数字实际上显示的是第一次点击按钮时下载 Default.aspxWebResource.axd 和 2 x ScriptResource.axd 的平均值,以及第二次点击按钮时下载 Default.aspx 的平均值。

为了证明这一点,我们将禁用下载引用文件(WebResource.axdScriptResource.axd)并再次运行测试。这可以通过在 Web 测试配置中禁用“Parse Dependent Requests”来实现。

图 12:禁用 Parse Dependent Requests

图 13:禁用 Parse Dependent Requests 后的负载测试结果

正如你在图 13 中看到的,在禁用“Parse Dependent Requests”的负载测试结果中,“Average Response Time”计数器的平均值现在显示了更正确的数据,尽管不完全是完美条件下的预期值。

Request/Page/Transaction/Test 计数器

现在是时候为不同类型的计数器提出清晰的定义了。有四种类型的计数器,每种代表不同的范围。

Request – 发送到服务器的任何请求(CSS、图像、JavaScript 等)。例如,如果测试一个带有单个图片的页面,平均请求时间将从 **每个** 下载的文件(页面本身、图像、CSS、JavaScript 等)计算。

Page – 页面是录制的*. 用户操作。它与请求不同,因为 Visual Studio 通常会执行比用户录制更多的操作。例如,打开一个页面时,用户输入地址并下载 HTML 内容,但它也会下载 CSS、图像、JavaScript 等。平均页面时间是下载所有这些文件所需的总时间。

Transaction – 事务是将多个页面分组为一个逻辑操作的方法。在负载测试结果中,可以分别查看每个事务的平均值。这使得事务成为一个非常强大的工具,我们稍后会再讨论。

Test – 测试计数器用于计算重放一个录制的 Web 测试对模拟用户所需的时间。例如,平均测试时间将显示重放一个录制的 Web 测试对模拟用户平均花费了多少时间。

技巧

使用“事务”收集功能性能数据

收集正确数据的第一个技巧是使用事务。你可以通过在负载测试中使用上下文菜单插入一个新事务。在我们的测试应用程序中,我们将使用两个事务:“AJAX postback”和“Full callback”,以区分第一个按钮(Full callback)的性能和第二个(AJAX postback)的性能。另外请记住,即使你不需要对多个请求进行分组,你仍然可以使用事务来为单独的用户操作赋予有意义的名称。

image

图 14:设置事务

现在让我们看看在 25 个用户的恒定负载下运行此测试后我们将获得什么结果。我们仍然可以看到 default.aspx 的通用响应时间,但现在,我们还将能够使用“Scenario1 -> WebTest2 -> Transactions”类别下的计数器来查看不同功能是如何工作的。

图 15:负载测试结果中的事务计数器

在此屏幕截图中,你可以看到“Full callback”的平均响应时间为 3.02s,“AJAXx postback”的平均响应时间为 0.3s,而平均总响应时间在两者之间(1.67s)。这意味着我们能够使用事务来区分一个 Web 测试中不同功能的性能。

分步负载

很多时候,你需要负载测试来确定你的系统可以支持多少并发用户。如果你使用恒定负载,你需要反复启动负载测试,并使用不同的并发用户数,直到找到系统开始出现故障的时候。虽然这是可能的,但毫无疑问是一种开销,因为你可以创建随时间增加用户数量的测试。

你可以在负载测试树的“... Load Pattern”节点中配置增量负载。你可能在下面的屏幕截图中一开始看不到这些设置,所以尝试将“Pattern”更改为“Step”以启用增量加载。完成此操作后,你可以配置步长的大小以及每个步长持续的秒数。

image

图 16:配置分步负载模式

image

图 17:分步负载配置参数

在上图中,你可以看到哪些设置修改了分步图的哪些部分。

重定向性能

默认情况下,Visual Studio 2008 将重定向计为一个请求,尽管技术上它是两个请求。如果页面响应重定向,则响应时间是通过将原始请求时间(响应 300 或 301 HTTP 状态的请求;在本例中为 9 秒)加上获取重定向页面内容所需的时间(实际呈现给用户的页面;在本例中为 3 秒)来计算的。这可能看起来是一个小问题,但如果你想确切地找出哪个部分出了问题,你仍然需要考虑这一点。

让我们创建另一个测试,其中用户点击 Redirect 按钮,看看用户在多快的时间内看到实际内容。

图 18:创建测试以测试重定向

当我们通过负载测试运行这些用户操作(参见图 19)时,结果是平均页面时间接近 12 秒(9 秒获取 HTTP 重定向代码,3 秒获取重定向的页面)。你还可能注意到平均响应时间并不理想。这是因为只有两个用户不足以计算一个好的平均值,但它向我们展示了平均响应时间有时是 3 秒,有时是 9 秒,有时是两者的平均值(6 秒)。这意味着在某些时段用户正在等待响应,而另一些用户收到了带有重定向状态(9 秒,还记得吗?)的响应。还有一些时段,用户正在等待重定向代码,而另一些用户收到了带有页面内容(3 秒)的响应。当然,也有一些时段,两个操作都在 5 秒的采样间隔内发生,平均为 6 秒。

图 19:重定向负载测试结果

幸运的是,我们有这两个数字(9 秒和 3 秒)显示在上面的图表中,因为模拟用户数量很少,但如果我们模拟更多用户,我们最终只会看到两者的平均值。为了区分获取重定向代码所需的时间和获取内容所需的时间,你需要做的第一件事是禁用 Web 测试中的“follow redirects”功能,这样 Visual Studio 就不会自动跟踪重定向头。接下来需要做的是手动请求重定向的页面,并将这两个请求放入不同的事务中以分离它们的计数器。

图 20:在负载测试中禁用“follow redirects”

现在我们可以用 25 个模拟用户运行我们的负载测试,并且仍然能够区分获取 HTTP 重定向代码和实际内容所需的时间。参见图 21。

图 21:改进的重定向负载测试结果

负载测试 Web 服务

Visual Studio 的负载测试功能不仅仅用于测试网站性能。你也可以轻松地用它来测试 Web 服务。要开始测试 Web 服务,请创建一个新的 Web 测试并添加一个新的 Web Service 请求,如下图所示。

图 22:创建 Web Service 请求

你应该能够使用 Web Service 请求属性窗口设置请求正文、头和其他属性,从而允许你创建更高级的请求。

分析负载测试结果

大多数情况下,负载测试结果清晰明了,但有几件事迟早会让你感到困惑。

第一件事是测试结果图中的间隙。大多数情况下,它们可以解释为在查看期间没有调用显示计数器。例如,如果你有一个模拟用户经历了许多事务(如“Open Page”、“Fill Questions”、“Validate answers”),那么“Validate Answers”事务数据仅在模拟用户验证答案时才会出现,而在其他间隔,此事务的平均值将会丢失。

下一件事是平均值可能比实际值略大。这是因为 Visual Studio 需要一些时间来处理响应、运行各种验证器、提取规则、递增计数器等。如果你分析的计数器的平均值很小,那么这个时间就会占有显著的比例。然而,对于较大的平均值(如 1 秒或 2 秒),这应该不是问题。

你可能遇到的另一件事是比较两个负载测试结果。请确保你进行测试的机器和测试环境都处于相似的负载下。在两台不同的机器上执行相同的测试可能会产生不同的结果。例如,请确保在进行负载测试时没有观看 YouTube,因为你的浏览器可能会导致你的机器响应变慢。

此外,用户负载并不总是正确的衡量标准。超过一定数量的并发用户后,系统将停止创建额外的请求,因为它无法处理它们。虽然模拟用户的数量是一个易于解释和展示的度量,但始终将其与“每秒请求数”进行比较,以确保它们成比例地变化。在下面的图中,你可以看到一个执行两个请求的测试。你可以看到,起初,每秒请求的数量增长速度快于模拟用户的数量,但在某个点,系统 just 无法处理更多请求,用户被迫在队列中等待响应,导致每秒请求的数量保持在同一水平。

图 23:系统因过多并发用户而拥塞

在另一台机器上打开负载测试结果

有时候,你可能想查看别人在另一台机器上进行的负载测试结果。你会很快发现,仅仅复制结果文件是不够的,因为大多数结果都存储在运行这些测试的机器的本地数据库中。以下是打开在另一台机器上进行的负载测试的完整流程。

  1. 首先,检查你是否安装了 Visual Studio 2008 Team Suite 或 Visual Studio Tester Edition。其他 VS 版本不支持负载测试!
  2. 索要 $(SolutionDir)\TestResults 文件夹下的 *.trx 文件和一个同名的文件夹。trx 文件由 VS 生成,应该包含测试结果,但在负载测试的情况下,它们包含编码的数据库连接字符串,其中存储了实际的测试。TRX 文件名如下所示:“username_MACHINE YYYY-MM-DD HH-mm-ss.trx”,因此你必须知道测试开始时间才能找到正确的文件。
  3. 索要负载测试结果数据库和日志的副本。正确路径取决于用于存储这些结果的数据库,但通常是
    • C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\ LoadTest.mdf
    • C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\ LoadTest_log.LDF
  4. 用接收到的文件替换你本地的 LoadTest.mdfLoadTest_log.LDF 副本。
  5. 在你的机器上创建并运行任何负载测试。
  6. 复制你刚刚通过在接收到的 *.trx 文件中运行负载测试而创建的 *.trx 文件中的“resultsRepositoryConnectString”属性值。
  7. 双击接收到的 *.trx 文件,或从 Visual Studio 中打开它。
  8. 你不会立即看到图表。要使它们出现,你需要双击“Test results”中的一个测试。

图 24:打开在另一台机器上进行的测试的图表
© . All rights reserved.