使用 Apache JMeter 規劃負載測試
在本節中,您會探索負載測試,並了解如何將負載測試新增至管線。 負載測試會使用 Apache JMeter 來模擬同時存取 Web 應用程式的多位使用者。 在「預備」環境中,這些測試會從在 Azure App Service 執行的應用程式擷取 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 要求取樣器新增至執行緒群組。 您可提供 Space Game 網站的主機名稱,這會在 Azure App Service 上的預備環境中執行。
上述案例會建立基本測試計劃。
執行測試計劃
JMeter 可讓您執行許多種測試。 您可以從 JMeter 圖形化使用者介面執行您的測試計劃。 但針對負載測試,JMeter 文件建議您從命令列執行測試計劃。
您可使用此命令來執行測試計劃:
apache-jmeter-5.4.1/bin/./jmeter -n -t LoadTest.jmx -o Results.xml
-n
引數指定以非 GUI 模式執行 JMeter。 -t
引數指定測試計劃檔 (LoadTest.jmx)。 -o
引數指定測試計劃檔 LoadTest.jmx。
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 毫秒的要求。
理想的要求時間平均應該少於一秒。 不超過 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 是最終報告檔案。 這個檔案會發佈至管線,以便小組可以視覺化這些結果。