使用 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 的樣子:

Apache JMeter 使用者介面的螢幕快照。

您將建立新的測試計劃檔案;例如 LoadTest.jmx。 接著,您會將 線程群組 新增至檔案。 每個仿真的用戶都會在其自己的線程上執行。 線程群組會控制用戶數目和每個使用者的要求數目。

下列範例顯示10個仿真的使用者(線程)。 每個使用者提出10個要求,因此系統總共會取得100個要求。

在 Apache JMeter 中指定線程群組的螢幕快照。

取樣器是由 JMeter 提出的單一要求。 JMeter 可以透過 HTTP、FTP、TCP 和其他數種通訊協議來查詢伺服器。 取樣器會產生加入至報表的結果。

接下來,您會將 Http 要求預設值Http 要求 取樣器新增至線程群組。 您會提供在 Azure App Service 上預備環境中執行的 Space Game 網站的主機名。

顯示在 Apache JMeter 中指定 HTTP 要求的螢幕快照。

前述案例會建立一個基本的測試計劃。

執行測試計劃

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 毫秒的請求。

理想的要求時間應該小於一秒。 不超過 10% 的要求都應花費一秒以上。 您可以設定 JMeter 來報告統計數據,例如最小值、最大值和平均回應時間或標準偏差。 您可以撰寫腳本來協助提供這項資訊。

若要將測試結果可視化,您必須以 Azure Pipelines 瞭解的格式提供它們。 Azure Pipelines 可以剖析包含測試結果的 XML 檔案,但檔案必須以支援的格式。 支援的格式包括 CTest、JUnit(包括 PHPUnit)、NUnit 2、NUnit 3、Visual Studio Test (TRX)和 xUnit 2。 您可以撰寫 XSLT 檔案,將 JMeter 結果轉換成 JUnit。

將報表轉換成 JUnit

XSLT 代表 XSL 轉換,或 eXtensible Stylesheet 語言轉換。 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 要求時間。

    它透過從每個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 是最終報表檔案。 此檔案會發佈至管線,讓小組可以將結果可視化。