使用 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 托管代理运行这些测试。 在 Space Game 场景中,你可能在过渡中运行这些测试。
创建测试计划
运行 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% 的请求时间会超过一秒。 可以将 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 转换,即可扩展样式表语言转换。 XSLT 文件类似于 XML 文件,但通过它能够将 XML 文档转换为另一种 XML 格式。
回顾负载测试的要求:
- 平均请求时间应少于一秒。
- 最多有 10% 的请求时间会超过一秒。
满足这些要求的 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 请求时间。
它通过选择每个
httpSample
元素的t
特性来收集此数据。 (./httpSample/@t
)每个失败消息。
它通过选择文档的所有
failureMessage
节点来收集此数据。 (./httpSample/assertionResult/failureMessage
)
XSLT 文件还将阈值设置为 1000 毫秒。 此响应时间是之前定义的最大值。
对于这些变量,XSLT 文件提供了测试总数和失败总数。 然后提供以下两个测试用例:
- 平均响应时间,如果平均值超过阈值 1000 毫秒,则失败。
- 最大响应时间,如果超过 10% 的请求超过阈值 1000 毫秒,则失败。
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 毫秒。 两个测试用例都不会生成失败,因为这两个时间都低于阈值 1000 毫秒。
稍后,你将在管道中运行这些测试。 可以考虑将 JMeter 写入的文件 (Results.xml) 作为不发布到管道的测试结果的中间文件。 JUnit.xml 是最终报告文件。 此文件会发布到管道,以便团队能够可视化结果。