使用事件中樞和IoT中樞的自訂外掛程式進行 Azure 負載測試

解決方案構想

本文說明解決方案概念。 您的雲端架構師可以使用本指南,協助視覺化此架構的一般實作的主要元件。 以本文為起點,設計符合您工作負載具體要求的完善解決方案。

此解決方案提供如何使用 Azure 負載測試的指引,此服務可讓您執行 Apache JMeter 腳本和自定義外掛程式來模擬使用者和裝置行為。 此解決方案也會說明如何設計關鍵效能指標(KPI),並開發儀錶板,以使用 Azure Functions 和 Azure 事件中樞在範例應用程式中監視和分析負載測試結果。 此範例使用事件中樞,但您可以將事件中樞用戶端變更為IoT中樞用戶端,將相同的方法套用至 Azure IoT 中樞用戶端。 本文假設您已熟悉 JMeter、其外掛程式和自定義外掛程式,以及 Functions 和事件中樞。

IoT 中樞包含比事件中樞更多的核心元件,包括分割區。 因此,本文所述的負載測試方法也適用於IoT中樞,且變更最少。

架構

若要執行負載測試,您需要測試計劃,這是一組指示 JMeter 在測試期間要執行的指示。 測試計劃可以包含多個測試案例,而且每個案例可以有不同的設定和組態。 例如,您可能有一個案例會模擬單一使用者存取 Web 應用程式,而另一個案例則模擬多個用戶同時存取相同的應用程式。

負載測試範例架構的圖表。

下載此架構的 Visio 檔案。

數據流

下列資料流程對應至上一個圖表:

  1. 模擬裝置會透過負載測試代理程式將數據傳送至事件中樞。 裝置的任何行為都可以使用 JMeter 自定義外掛程式來模擬。 負載測試代理程式會在執行任何類型的模擬裝置的自定義外掛程式之後,將數據傳送至事件中樞。

  2. 事件中樞會觸發處理數據的 Azure 函式應用程式,並將其傳送至其他下游服務,例如 Azure SQL Database 和 Azure Digital Twins。

  3. Azure 監視器會監視函式應用程式和事件中樞。

  4. 負載測試會從 Azure 監視器收集數據,並將其顯示在儀錶板中。

元件

此範例使用下列元件:

  • 負載測試:使用負載測試來執行 Apache JMeter 腳本和自定義外掛程式,以模擬使用者和裝置行為。 負載測試提供 Web 型介面來管理和執行負載測試,以及一組 API 來自動化程式。 負載測試是完全受控的服務,這表示您不需要管理伺服器或基礎結構。 在此架構中,負載測試會上傳 JMeter 腳本和自訂插件,這是這些腳本運行的計算資源。

  • 事件中樞:事件中樞是雲端式事件處理服務,可用來即時收集、處理和分析來自各種來源的事件和串流數據。 事件中樞支援多個通訊協定,包括進階消息佇列通訊協定(AMQP)、HTTPS、Kafka 通訊協定、消息佇列遙測傳輸(MQTT)和透過 WebSocket 的 AMQP。 此架構是以事件為基礎,因此負載測試會填入事件以負載測試工作負載。

  • IoT 中樞:IoT 中樞是雲端裝載的受控服務,可作為IoT應用程式與其連結裝置之間通訊的中央訊息中樞。 您可以放心且安全地連結數百萬部裝置及其後端解決方案。 幾乎任何裝置都可以連線到IoT中樞。 您可以將事件中樞客戶端變更為 IoT 中樞客戶端,以便調整此架構來使用 IoT 中樞。

  • Azure Functions:Functions 是一種無伺服器計算服務,可讓您用來執行程式碼,而不需要管理伺服器或基礎結構。 它支援多種程式設計語言,包括 C#、F#、Java、JavaScript、PowerShell、Python 和 TypeScript。 此架構會使用 Functions 作為主要計算層。 事件中樞的事件數據會觸發並擴展函式應用程式。

  • JMeter GUI:JMeter GUI 是一種開放原始碼負載測試工具,主要用於測試 Web 應用程式的效能。 不過,您也可以使用它來測試其他類型的應用程式,例如SOAP和REST Web服務、FTP 伺服器和資料庫。

  • Azure 監視器:Azure 監視器提供 Azure 資源的監視和警示功能。 使用它來監視應用程式和基礎結構的效能和健康情況。 在此架構中,Azure 監視器會在負載測試期間監視 Azure 基礎結構元件的健全狀況。

案例詳細資料

您可以使用負載測試來套用現有的 Apache JMeter 腳本,並在任何 Azure 資源上以雲端規模執行負載測試。

JMeter 可讓測試人員建立和執行負載測試、壓力測試和功能測試。 其會模擬多個用戶同時存取 Web 應用程式,讓測試人員能夠識別潛在的效能瓶頸或其他在負載過重時可能發生的問題。 您可以使用 JMeter 來測量各種效能計量,例如響應時間、輸送量和錯誤率。

JMeter 會使用 GUI 型介面來允許使用者建立測試計劃,其中包括具有不同設定和組態的多個測試案例。 測試人員也可以使用外掛程式或撰寫自訂程式碼來自訂 JMeter。 外掛程式可協助使用者使用使用非 HTTP 通訊協定的服務,例如 AMQP 和 WebSocket。

JMeter 提供各種不同的功能和函式來進行負載測試,但內建功能可能未涵蓋特定的使用案例或需求。 藉由開發自定義外掛程式,測試人員可以新增功能或自定義現有功能,以更符合其需求。

例如,您可以開發自定義外掛程式來模擬特定類型的用戶行為,或產生更真實的測試數據。 您也可以開發自定義外掛程式來整合 JMeter 與其他工具或系統,例如記錄和報告工具,或持續整合和持續部署 (CI/CD) 管線。 自定義外掛程式可協助簡化測試程式,並更輕鬆地將負載測試納入整體軟體開發工作流程。 他們可讓測試人員根據自己的特定需求量身打造 JMeter,並改善負載測試工作的精確度和有效性。

在此範例中,裝置會報告特定時段的溫度和濕度。 此範例會使用自定義 JMeter 外掛程式來模擬此行為。 自定義外掛程式的目前實作 會使用提供的範本產生隨機數據。 不過,外掛程式可以包含任何裝置的任何可能複雜行為。 在此範例中,裝置會將數據傳送至 Azure 中的事件中樞。 事件中樞會觸發 Azure 函式應用程式,此應用程式會處理數據,並將其傳送至其他下游服務,例如 SQL Database。 Azure Functions 是架構測試的服務。 測試計劃旨在模擬裝置的行為,並將數據傳送至事件中樞。

潛在使用案例

搭配自定義外掛程式使用負載測試,在各種案例中很有用,例如:

  • 測試使用非 HTTP 通訊協定的應用程式效能,例如 AMQP 和 WebSocket。
  • 測試使用自定義通訊協定的應用程式效能。
  • 測試使用非Microsoft SDK 的應用程式效能。
  • 模擬特定類型的用戶或裝置行為。
  • 產生更真實的測試數據。

自訂外掛程式

在 JMeter 中,自定義外掛程式是您可以新增以擴充其預設功能的軟體元件。 自定義外掛程式會將新功能、函式或整合新增至 JMeter。 您可以使用 Java 程式設計語言和 JMeter 外掛程式開發工具套件 (PDK) 來開發自訂外掛程式。 PDK 提供一組工具和 API,可協助您建立新的外掛程式,包括 GUI 元素、接聽程式和取樣器。

若要在 JMeter 中實作事件中樞的自訂取樣器,請遵循 負載測試 JMeter 外掛程式中的指示。 實作自定義取樣器之後,您可以在負載測試的 JMeter 測試計劃中使用它,就像任何其他取樣器一樣。

您可以使用控制虛擬使用者和裝置等線程數目的線程群組來執行特定案例,以實作測試計劃。 每個線程群組可以有不同的線程數目、增加期間、循環計數和持續時間的不同設定。 視測試計劃組態和應用程式需求而定,線程群組可以循序或平行執行。 您可以將取樣器新增至線程群組、設定其參數,並視需要加以設定。 自定義取樣器可以是 JMeter 中功能強大的工具,可讓您模擬內建取樣器不支援的複雜案例和要求。

使用自定義外掛程式建立 Apache JMeter 腳稿

在本節中,您會建立範例 JMeter 測試腳本,以使用事件中樞載入測試應用程式。

若要建立範例 JMeter 測試腳本:

  1. 在文本編輯器中建立 LoadTest.jmx 檔案,並將下列代碼段貼到檔案中。 此腳本會模擬 36 部同時將事件傳送至事件中樞的虛擬機負載測試。 完成需要 10 分鐘的時間。

    <?xml version="1.0" encoding="UTF-8"?>
    <jmeterTestPlan version="1.2" properties="5.0" jmeter="5.5">
        <hashTree>
        <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
            <stringProp name="TestPlan.comments"></stringProp>
            <boolProp name="TestPlan.functional_mode">false</boolProp>
            <boolProp name="TestPlan.tearDown_on_shutdown">true</boolProp>
            <boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
            <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
                <collectionProp name="Arguments.arguments"/>
            </elementProp>
            <stringProp name="TestPlan.user_define_classpath"></stringProp>
        </TestPlan>
        <hashTree>
            <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true">
                <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
                <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
                    <boolProp name="LoopController.continue_forever">false</boolProp>
                    <intProp name="LoopController.loops">-1</intProp>
                </elementProp>
                <stringProp name="ThreadGroup.num_threads">36</stringProp>
                <stringProp name="ThreadGroup.ramp_time">20</stringProp>
                <boolProp name="ThreadGroup.scheduler">true</boolProp>
                <stringProp name="ThreadGroup.duration">600</stringProp>
                <stringProp name="ThreadGroup.delay"></stringProp>
                <boolProp name="ThreadGroup.same_user_on_next_iteration">false</boolProp>
            </ThreadGroup>
            <hashTree>
                 <com.microsoft.eventhubplugin.EventHubPlugin guiclass="com.microsoft.eventhubplugin.EventHubPluginGui" testclass="com.microsoft.eventhubplugin.EventHubPlugin" testname="Azure Event Hubs Sampler" enabled="true">
                    <!-- Azure Event Hub connection configuration using Managed Identity (see repository for instructions) -->
                    <boolProp name="useManagedIdentity">true</boolProp>
                    <stringProp name="eventHubNamespace">telemetry-ehn.servicebus.windows.net</stringProp>
                    <stringProp name="eventHubName">telemetry-data-changed-eh</stringProp>
                    <stringProp name="liquidTemplateFileName">StreamingDataTemplate.liquid</stringProp>
                </com.microsoft.eventhubplugin.EventHubPlugin>
            </hashTree>
        </hashTree>
        </hashTree>
    </jmeterTestPlan>
    

    com.microsoft.eventhubplugin.EventHubPluginGui 和 com.microsoft.eventhubplugin.EventHubPlugin 的實作可在 Azure 範例中獲得。

  2. 在檔案中,使用測試執行器指派的受控識別來設定事件中樞連線值。 該身分識別必須具有事件中樞實例的寫入許可權。

  3. 在檔案中,將節點的值 eventHubName 設定為事件中樞名稱,例如 telemetry-data-changed-eh。

  4. 將 liquidTemplateFileName 節點的值設定為包含傳送至事件中樞之訊息的檔案。 例如,建立名為 StreamingDataTemplate.liquid 的檔案:

    {
        {% assign numberOfMachines = 36 %}
        {% assign machineId = dataGenerator.randomNaturalNumber | modulo: numberOfMachines %}
        "MachineId": "{{machineId | prepend: '0000000000000000000000000000000000000000' | slice: -27, 27 }}",
        "Temperature": {{dataGenerator.randomInt | modulo: 100 }},
        "Humidity": {{dataGenerator.randomInt | modulo: 100 }}
    }
    

    在這裡範例中,事件中樞訊息的承載是 JSON 物件,其具有三個屬性:MachineId、Temperature和 Humidity。 MachineId 是長度為 27 個字元的隨機產生標識碼,Temperature 和 Humidity 為小於 100 的隨機整數。 此檔案是液體範本語法。 Liquid 範本是各種 Web 開發架構中使用的熱門範本化語言。 Liquid 範本可讓開發人員建立可輕鬆更新和修改的動態內容。 它們可讓您將變數、條件、迴圈和其他動態元素插入事件中樞訊息。 語法很簡單,而且有許多在線資源可協助您開始使用。 Liquid 範本提供強大且靈活的方法來建立動態、可自定義的訊息。

  5. 儲存並關閉檔案。

    重要

    請勿在 JMeter 腳本的取樣器名稱中包含任何個人資料。 取樣器名稱會出現在負載測試測試結果儀錶板中。 液體範本以及 JMeter 腳本檔案範例,可在 Azure 範例中下載。

將自定義外掛程式從事件中樞更新至IoT中樞

自定義外掛程式會使用事件中樞作為主要目標資源。 下列組態是事件中樞的 SDK 用戶端設定:

EventHubProducerClient producer = null;
EventHubClientBuilder producerBuilder = new EventHubClientBuilder();

producerBuilder.credential(getEventHubNamespace(), getEventHubName(), new DefaultAzureCredentialBuilder().build());
producer = producerBuilder.buildProducerClient();

EventDataBatch batch = producer.createBatch(new CreateBatchOptions());
batch.tryAdd(new EventData(msg));
producer.send(batch);

下列範例示範如何重複使用相同的解決方案、新增IoT相依性,以及將SDK用戶端變更為使用IoT中樞:

IotHubServiceClientProtocol protocol = IotHubServiceClientProtocol.AMQPS;
ServiceClient client = new ServiceClient(getIoTHostName(), new DefaultAzureCredentialBuilder().build(), protocol);
client.open();

Message message = new Message(msg);
client.send(getDeviceName(), message);

client.close();

使用新的外掛程式執行負載測試

當負載測試啟動負載測試時,它會先將 JMeter 腳本連同所有其他檔案一起部署到測試引擎實例。 執行測試之前,請移至參數索引標籤,以定義並設定任何必要的參數。 如需詳細資訊,請參閱 使用 Apache JMeter 外掛程式和負載測試自定義負載測試。

為環境設置效能測試

針對效能測試,測試環境必須類似於生產環境。 此範例會使用下列環境進行效能測試,以進一步了解系統的容量和效能。

服務 組態
事件中樞 具有一個處理單位的進階
Azure Functions 具有進階方案 (EP1) 的 Linux - 210 ACU、3.5 GB 記憶體和 1 個 vCPU 對等Standard_D1_v2
區域 美國東部

為任何 Azure 服務選擇正確的服務層級,包括事件中心和 Azure Functions,是一個複雜的程式,而且取決於許多因素。 如需詳細資訊,請參閱 事件中樞定價 和 Functions 定價。

設計效能測試的 KPI

您必須先定義商務需求和系統架構,才能設計效能測試的 KPI。 商務需求會告訴您您想要測量的 KPI,例如響應時間、輸送量或錯誤率。 系統架構會告訴您如何測試每個元件的效能,例如 Web 伺服器、資料庫或 API。 它也可協助您選擇最佳的效能測試策略,例如負載測試、壓力測試或耐力測試。

此範例具有下列商務需求:

  • 系統每秒可以處理1,000個要求。
  • 系統可靠性高於 0.99。
  • 系統可同時處理1,000台裝置報告遙測資料。
  • 您可以根據系統可支援的裝置數目來指定系統的最大容量。 例如,系統可以支援 1,000 部並行裝置,其容量是目前容量的三倍。

若要測量系統是否符合這些需求,您可以使用下列 KPI 來進行效能測試:

KPI 描述
RPS 事件中樞每秒請求數
負荷 效能測試期間傳送至事件中樞的負載或要求數目
IR 函數調用次數或是擷取速率的數目
RT Azure Functions 運行時間的平均時間
AMU Azure Functions 的平均記憶體使用量
鍶 所有功能應用程式調用的成功率
ARS 披索 SQL Server 或微服務等服務的下游服務回應時間平均
DF 相依性失敗計數,包括內部功能程式應用錯誤
MRPS 事件中樞中沒有待辦專案的最大 RPS (系統容量)

衡量 KPI

要測量 KPI,您需要一個效能測試策略。 此策略會定義每個元件的效能測試方法。 此範例使用下列效能測試策略。

  • 事件中樞: 事件中樞的效能測試方法是將許多訊息傳送至事件中樞,然後測量 RPS 和 LOAD。 RPS 是每秒傳送至事件中樞的訊息數目。 LOAD 是效能測試期間傳送至事件中樞的訊息總數。 負載測試可以測量 RPS 和 LOAD。

  • Azure Functions: Functions 的效能測試方法是測量下列計量。

    • IR
    • RT
    • AMU
    • 鍶
    • ARS 披索
    • DF

Azure 監視器可以測量AMU、ARS和 DF,但無法測量 IR、RT 或 SR。 若要使用 Azure 監視器測量 KPI,請啟用 Azure Functions 的 Application Insights。 如需詳細資訊,請參閱 啟用ApplicationInsights整合。

啟用 Azure 監視器之後,您可以使用下列查詢來測量 KPI:

  • 紅外: FunctionAppLogs | where Category startswith "name-space-of-your-function" and Message startswith "Executed" | summarize count() by FunctionName, Level, bin(TimeGenerated, 1h) | order by FunctionName desc

  • RT: FunctionAppLogs| where Category startswith "name-space-of-your-function" and Message startswith "Executed "| parse Message with "Executed " Name " (" Result ", Id=" Id ", Duration=" Duration:long "ms)"| project TimeGenerated, Message, FunctionName, Result, FunctionInvocationId, Duration

  • 鍶: FunctionAppLogs| where Category startswith "name-space-of-your-function" and Message startswith "Executed" | summarize Success=countif(Level == "Information" ), Total=count() by FunctionName| extend Result=Success*100.0/Total| project FunctionName, Result| order by FunctionName desc

Azure 監視器儀錶板範例

下圖顯示 Azure 監視器儀錶板的範例。 它會根據先前的查詢顯示 Azure Functions 的 KPI。

顯示 Azure 監視器儀錶板範例的螢幕快照。

參與者

Microsoft維護本文。 下列參與者撰寫本文。

主要作者:

若要查看非公開的 LinkedIn 個人檔案,請登入 LinkedIn。

下一步