使用 Apache JMeter 规划负载测试
在本部分中,你将了解负载测试,并了解如何向管道添加负载测试。 负载测试使用 Apache JMeter 模拟同时访问 Web 应用的多个用户。 测试从运行在 Azure 应用服务中的 暂存环境 的应用程序提取 Web 内容。
Tim 首先在笔记本电脑上打开 Apache JMeter 用户界面。 他运行一个基本的测试计划。 然后 Tim 和 Mara 将测试计划导出到可从命令行运行的文件。 最后,将任务添加到 Azure Pipelines,以便在 过渡期间运行负载测试。
注释
为简洁起见,无需在本地计算机上安装 Apache JMeter。 你可以跟着一起阅读。
从 Apache JMeter 运行负载测试
Apache JMeter 是一种开源负载测试工具,用于分析和度量性能。 它生成的报表是一个 XML 文件。
Azure Pipelines 可以读取 Apache JMeter 报表并生成图形。 无需任何特殊的硬件即可运行这些测试,因此可以使用Microsoft托管的代理来运行这些测试。 在太空游戏场景中,你可能会在预发布环境中运行这些测试。
创建测试计划
下面是运行 Linux 的笔记本电脑上的 Apache JMeter 的外观:
你将创建新的测试计划文件;例如 LoadTest.jmx。 然后将 线程组 添加到该文件。 每个模拟用户在其自己的线程上运行。 线程组控制用户数和每个用户的请求数。
以下示例显示了 10 个模拟用户(线程)。 每个用户发出 10 个请求,因此系统总共收到 100 个请求。
采样器是由 JMeter 发出的单个请求。 JMeter 可以通过 HTTP、FTP、TCP 和其他几种协议查询服务器。 采样器生成添加到报表的结果。
接下来,将 Http 请求默认值 和 Http 请求 采样器添加到线程组。 你将提供在 Azure 应用服务上的过渡环境中运行的 Space Game 网站的主机名。
上述方案创建基本测试计划。
运行测试计划
使用 JMeter 可以运行多种测试。 可以从 JMeter 图形用户界面运行测试计划。 但是,对于负载测试,JMeter 文档建议从命令行运行测试计划。
你将使用以下命令运行测试计划:
apache-jmeter-5.4.1/bin/./jmeter -n -t LoadTest.jmx -o Results.xml
该 -n 参数指定在非 GUI 模式下运行 JMeter。 该 -t 参数指定测试计划文件 LoadTest.jmx。 该 -o 参数指定报表文件 ,Results.xml。
JMeter 运行并生成报表文件, Results.xml。 此文件示例显示了前几个结果:
<?xml version="1.0" encoding="UTF-8"?>
<testResults version="1.2">
<httpSample t="180" it="0" lt="95" ct="35" ts="1569306009772" s="true" lb="HTTP Request" rc="200" rm="OK" tn="Thread Group 1-1" dt="text" by="40871" sby="144" ng="1" na="1">
<java.net.URL>http://tailspin-space-game-web-staging-1234.azurewebsites.net/</java.net.URL>
</httpSample>
<httpSample t="174" it="0" lt="96" ct="38" ts="1569306009955" s="true" lb="HTTP Request" rc="200" rm="OK" tn="Thread Group 1-1" dt="text" by="40869" sby="144" ng="1" na="1">
<java.net.URL>http://tailspin-space-game-web-staging-1234.azurewebsites.net/</java.net.URL>
</httpSample>
<httpSample t="160" it="0" lt="121" ct="35" ts="1569306010131" s="true" lb="HTTP Request" rc="200" rm="OK" tn="Thread Group 1-1" dt="text" by="40879" sby="144" ng="2" na="2">
<java.net.URL>http://tailspin-space-game-web-staging-1234.azurewebsites.net/</java.net.URL>
</httpSample>
每个示例在报表中生成一个节点。 该 t 属性指定响应时间(毫秒)。 在这里,你看到三个请求分别用了 180 毫秒、174 毫秒和 160 毫秒。
理想的请求时间应小于 1 秒。 不超过 10% 的请求应占用 1 秒以上。 可以将 JMeter 配置为报告统计信息,例如最小、最大值和平均响应时间或标准偏差。 可以编写脚本来帮助提供此信息。
若要可视化测试结果,需要以 Azure Pipelines 理解的格式提供它们。 Azure Pipelines 可以分析包含测试结果的 XML 文件,但该文件需要采用受支持的格式。 支持的格式包括 CTest、JUnit(包括 PHPUnit)、NUnit 2、NUnit 3、Visual Studio Test(TRX)和 xUnit 2。 可以编写将 JMeter 结果转换为 JUnit 的 XSLT 文件。
将报表转换为 JUnit
XSLT 代表 XSL 转换或 eXtensible Stylesheet 语言转换。 XSLT 文件类似于 XML 文件,但它使你可以将 XML 文档转换为另一种 XML 格式。
回顾负载测试的要求:
- 平均请求时间应小于 1 秒。
- 不超过 10% 的请求应占用 1 秒以上。
下面是满足这些要求的 XSLT 文件如下所示:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:math="http://exslt.org/math">
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
<xsl:template match="/testResults">
<xsl:variable name="times" select="./httpSample/@t" />
<xsl:variable name="failures" select="./httpSample/assertionResult/failureMessage" />
<xsl:variable name="threshold" select="1000" />
<testsuite>
<xsl:attribute name="tests"><xsl:value-of select="count($times)" /></xsl:attribute>
<xsl:attribute name="failures"><xsl:value-of select="count($failures)" /></xsl:attribute>
<testcase>
<xsl:variable name="avg-time" select="sum($times) div count($times)" />
<xsl:attribute name="name">Average Response Time</xsl:attribute>
<xsl:attribute name="time"><xsl:value-of select="format-number($avg-time div 1000,'#.##')"/></xsl:attribute>
<xsl:if test="$avg-time > $threshold">
<failure>Average response time of <xsl:value-of select="format-number($avg-time,'#.##')"/> exceeds <xsl:value-of select="$threshold"/> ms threshold.</failure>
</xsl:if>
</testcase>
<testcase>
<xsl:variable name="exceeds-threshold" select="count($times[. > $threshold])" />
<xsl:attribute name="name">Max Response Time</xsl:attribute>
<xsl:attribute name="time"><xsl:value-of select="math:max($times) div 1000"/></xsl:attribute>
<xsl:if test="$exceeds-threshold > count($times) * 0.1">
<failure><xsl:value-of select="format-number($exceeds-threshold div count($times) * 100,'#.##')"/>% of requests exceed <xsl:value-of select="$threshold"/> ms threshold.</failure>
</xsl:if>
</testcase>
</testsuite>
</xsl:template>
</xsl:stylesheet>
我们不会深入探讨 XSL 在这里的工作原理。 但概括而言,此文件首先从 JMeter 输出中收集以下数据:
每个 HTTP 请求时间。
它通过从每个
t元素中选择httpSample属性来收集此数据。 (./httpSample/@t)每条失败消息。
它通过从文档中选择所有
failureMessage节点来收集此数据。 (./httpSample/assertionResult/failureMessage)
XSLT 文件还将阈值设置为 1,000 毫秒。 此响应时间是我们之前定义的最大值。
鉴于这些变量,XSLT 文件提供测试总数和失败总数。 然后,它提供以下两个测试用例:
- 平均响应时间,如果平均值超过阈值 1,000 毫秒,则失败。
- 最大响应时间,如果超过 10% 的请求超过阈值 1,000 毫秒,则失败。
XSLT 的结果与 Azure Pipelines 理解的 JUnit 格式匹配。 可以命名 XSLT 文件 JMeter2JUnit.xsl。
接下来,需要 XSLT 处理器。 在此示例中,我们将使用 xsltproc,它是将 XSLT 样式表应用于 XML 文档的命令行工具。
可以安装 xsltproc ,如下所示:
sudo apt-get install xsltproc
接下来,运行 xsltproc 将 JMeter 报表转换为 JUnit:
xsltproc JMeter2JUnit.xsl Results.xml > JUnit.xml
下面是生成的 JUnit 文件, JUnit.xml:
<?xml version="1.0" encoding="UTF-8"?>
<testsuite xmlns:math="http://exslt.org/math" tests="100" failures="0">
<testcase name="Average Response Time" time="0.17"/>
<testcase name="Max Response Time" time="0.373"/>
</testsuite>
在此示例中,平均响应时间为 170 毫秒。 最大响应时间为 373 毫秒。 两个测试用例都不会生成失败,因为两次都低于 1,000 毫秒的阈值。
稍后,你将在管道中运行这些测试。 可以将 JMeter 写入的文件Results.xml视为未发布到管道测试结果的中间文件。 JUnit.xml 是最终报告文件。 此文件将发布到管道,以便团队能够直观显示结果。