カスタム プラグインを使用した Azure Load Testing

ソリューションのアイデア

このアーティクルはソリューションのアイデアです。 このコンテンツにさらに多くの情報 (想定されるユース ケース、代替サービス、実装に関する考慮事項、価格ガイダンスなど) の掲載をご希望の方は、GitHub のフィードバックでお知らせください。

Azure Load Testing は、Apache JMeter スクリプトとカスタム プラグインを実行してユーザーとデバイスの動作をシミュレートできるサービスです。このソリューションでは、その使用方法についてガイダンスを提供します。 このソリューションでは、Azure Functions と Azure Event Hubs を使用するサンプル アプリケーションでロード テストの結果を監視および分析するためのダッシュボードを開発する方法と、KPI (主要性能指標) を設計する方法についても説明します。 この記事では、JMeter とそのプラグインおよびカスタム プラグインのほか、Azure Functions と Event Hubs に関する知識があることを前提としています。

Architecture

ロード テストを実行するには、テスト プランが必要です。これは、テスト中の JMeter の動作を取り決めた一連の手順です。 テスト プランには、それぞれ設定と構成が異なる複数のテスト シナリオを含めることができます。 たとえば、1 人のユーザーによる Web アプリケーションへのアクセスをシミュレートするシナリオと、同じアプリケーションへの複数ユーザーによる同時アクセスをシミュレートするシナリオが考えられます。

テスト プランには、それぞれ設定と構成が異なる複数のテスト ケースを含めることもできます。 ここでは、一定期間中の温度と湿度を報告するデバイスがあることを想定しています。 このデバイスは、Azure のイベント ハブにデータを送信します。 イベント ハブは、データを処理したうえで Azure SQL Database などの他のダウンストリーム サービスにデータを送信する Azure 関数をトリガーします。 この Azure 関数が、テスト対象のサービスです。 テスト プランは、このデバイスの動作をシミュレートし、イベント ハブにデータを送信するように設計されています。

Diagram of a sample architecture for load testing.

このアーキテクチャの Visio ファイルをダウンロードします。

データフロー

この例のデータフローは次のようになります。

  1. シミュレートされたデバイスが、Azure Load Testing エージェントを介してイベント ハブにデータを送信します。 デバイスの動作はすべて、JMeter のカスタム プラグインを使用してシミュレートできます。 Azure Load Test エージェントは、あらゆる種類のシミュレートされたデバイスに対応するカスタム プラグインを実行した後、イベント ハブにデータを送信します。
  2. イベント ハブは、データを処理したうえで Azure SQL Database や Azure Digital Twins などの他のダウンストリーム サービスにデータを送信する Azure 関数をトリガーします。
  3. Azure 関数と Event Hubs を監視するために Azure Monitor サービスが使用されます。
  4. Azure Load Testing サービスが、Azure Monitor サービスからデータを収集し、ダッシュボードに表示します。

コンポーネント

この例では、以下のコンポーネントを使用します。

  • Azure Load Testing: Azure Load Testing を使用すると、Apache JMeter スクリプトとカスタム プラグインを実行して、ユーザーとデバイスの動作をシミュレートできます。 ロード テストを管理および実行するための Web ベースのインターフェイスと、プロセスの自動化に使用できる一連の API が提供されます。 Azure Load Testing はフル マネージド サービスです。したがって、サーバーやインフラストラクチャの管理について心配する必要はありません。 JMeter スクリプトとカスタム プラグインをアップロードすると、残りの部分は Azure Load Testing によって処理されます。
  • Azure Event Hubs: Azure Event Hubs はクラウドベースのイベント処理サービスであり、さまざまなソースからイベントおよびストリーミング データをリアルタイムで収集、処理、分析するために使用できます。 Event Hubs では、AMQP (Advanced Message Queuing Protocol)、HTTPS、Kafka Protocol、MQTT (Message Queuing Telemetry Transport)、AMQP over WebSockets など、複数のプロトコルがサポートされています。 適切なプロトコルを選択するには、扱うデータの種類、アプリケーション固有の要件、プロトコル自体の機能や制限など、いくつかの要因を考慮する必要があります。
  • Azure Functions: Azure Functions は、サーバーやインフラストラクチャを管理せずにコードを実行できる、サーバーレス コンピューティング サービスです。 C#、F#、Java、JavaScript、PowerShell、Python、TypeScript など、複数のプログラミング言語がサポートされています。 Azure Functions では、Event Hubs だけでなく、Azure Storage や Azure Cosmos DB など他のソースからのイベントやストリーミング データも処理できます。
  • JMeter GUI: JMeter GUI は、主に Web アプリケーションのパフォーマンスをテストするために使用されるオープンソースのロード テスト ツールです。 元は Web アプリケーションをテストするために開発されたものです。 ただし、SOAP および REST Web サービス、FTP サーバー、データベースなど、他の種類のアプリケーションをテストするためにも使用できます。
  • Azure Monitor: Azure Monitor には、Azure リソースに対する監視とアラートの機能が用意されています。 これにより、アプリケーションのパフォーマンスおよび正常性と、基になるインフラストラクチャも監視できます。 Azure Monitor を使用すると、Event Hubs と Azure Functions のほか、Azure Storage や Azure Cosmos DB などの他の Azure サービスも監視できます。

シナリオの詳細

Azure Load Testing では、既存の Apache JMeter スクリプトを使用し、任意の Azure リソースで、クラウド規模でのロード テストを実行できます。

JMeter により、テスト担当者はロード テスト、ストレス テスト、機能テストを作成して実行できます。 複数のユーザーによる Web アプリケーションへの同時アクセスをシミュレートすることで、潜在的なパフォーマンスのボトルネックや、高負荷時に発生する可能性のあるその他の問題を特定できます。 JMeter は、応答時間、スループット、エラー率など、さまざまなパフォーマンス メトリックの測定に使用できます。

ユーザーは、JMeter の GUI ベースのインターフェイスを使用してテスト プランを作成できます。テスト プランには、それぞれ設定と構成が異なる複数のテスト シナリオを含めることができます。 テスト担当者は、プラグインの使用またはカスタム コードの作成によって JMeter をカスタマイズし、独自に機能を追加できます。 プラグインは、AMQP や Websocket など、HTTP 以外のプロトコルを使用するサービスを使用する場合に役立ちます。

JMeter にはロード テスト用に多様な機能が用意されていますが、組み込みの機能で対応していない特定のユース ケースや要件が存在することもあります。 カスタム プラグインを作成することで、テスト担当者は新たな機能を追加することも、ニーズに合わせて既存の機能をカスタマイズすることもできます。

たとえば、ユーザーの具体的な動作のシミュレートや、より現実的なテスト データの生成のために、カスタム プラグインを作成できます。 さらに、カスタム プラグインを作成することで、ログ記録ツールやレポート ツール、CI/CD (継続的インテグレーションおよび継続的デプロイ) パイプラインなど、他のツールやシステムに JMeter を統合することもできます。 カスタム プラグインがあれば、テスト プロセスを合理化し、ソフトウェア開発ワークフロー全体にロード テストを簡単に組み込むことができます。 全体的には、具体的なニーズに合わせて JMeter を調整し、ロード テスト作業の精度と有効性を向上させるためには、カスタム プラグインが役立ちます。

ここでは、一定期間にわたって温度と湿度を報告するデバイスがあることを想定しています。 この単純な動作は、カスタムの JMeter プラグインを使用してシミュレートできます。 ここで提供されているカスタム プラグインの現在の実装では、提供されたテンプレートによりランダム データが生成されます。 ただしプラグインには、デバイスに関して考えられる、どのように複雑な動作も含めることができます。 この例では、デバイスから Azure のイベント ハブにデータが送信されます。 イベント ハブは、データを処理したうえで、Azure SQL Database などの他のダウンストリーム サービスにデータを送信する Azure 関数をトリガーします。 この Azure 関数が、テスト対象のサービスです。 テスト プランは、このデバイスの動作をシミュレートし、イベント ハブにデータを送信するように設計されています。

考えられるユース ケース

カスタム プラグインと共に Azure Load Testing を使用すると、以下のようなさまざまなシナリオに役立ちます。

  • AMQP や Websocket など、HTTP 以外のプロトコルを使用するアプリケーションのパフォーマンス テスト。
  • カスタム プロトコルを使用するアプリケーションのパフォーマンス テスト。
  • Microsoft 以外の SDK を使用するアプリケーションのパフォーマンス テスト。
  • ユーザーまたはデバイスの具体的な動作のシミュレーションや、より現実的なテスト データの生成。

カスタム プラグイン

JMeter のコンテキストでのカスタム プラグインは、JMeter に追加して独自に機能を拡張するためのソフトウェア コンポーネントです。 ユーザーまたは Microsoft 以外の開発者は、JMeter に新しい機能、関数、または統合を追加するためのカスタム プラグインを作成できます。 カスタム プラグインは、Java プログラミング言語と JMeter プラグイン開発キット (PDK) を使用して開発できます。 PDK には、GUI 要素、リスナー、サンプラーなど、新しいプラグインを容易に作成するためのツールや API が用意されています。

カスタム プラグインを使用すると、JMeter に幅広い機能を追加できます。 また、ログ ツールやレポート ツールなど、他のシステムに JMeter を統合することも、テスト データに他のデータ ソースを使用することもできます。 全体として、カスタム プラグインを使用すると、JMeter を拡張して具体的なニーズを満たし、ロード テスト作業の精度と有効性を向上させることができます。

JMeter に Event Hubs 用のカスタム サンプラーを実装するには、Azure Load Testing プラグインの説明に記載されている手順に従います。 カスタム サンプラーを実装すると、他のサンプラーと同様、Azure Load Test で独自の JMeter テスト プランに使用できます。

テスト プランを実装するには、特定のシナリオを実行するスレッド (仮想ユーザーとデバイス) の数を制御するスレッド グループを使用します。 スレッド グループごとに、スレッド数、ランプアップ期間、ループ数、期間を別々に設定できます。 スレッド グループは、テスト プランの構成とアプリケーションの要件に応じて、順次または並列に実行できます。 サンプラーをスレッド グループに追加してパラメーターを設定し、必要に応じて構成できます。 カスタム サンプラーは JMeter の強力なツールです。これを活用することにより、組み込みのサンプラーでサポートされていない複雑なシナリオや要求をシミュレートできます。

カスタム プラグインを使用して Apache JMeter スクリプトを作成する

このセクションでは、Event Hubs でアプリケーションのロード テストを行うためのサンプル JMeter テスト スクリプトを作成します。

サンプル JMeter テスト スクリプトを作成するには:

  1. ローカル コンピューターに、LoadTest.jmx ファイルを作成します。

    touch LoadTest.jmx
    
  2. テキスト エディターで 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">
                <stringProp name="eventHubConnectionVarName">EventHubConnectionString</stringProp>
                <stringProp name="eventHubName">telemetry-data-changed-eh</stringProp>
                <stringProp name="liquidTemplateFileName">StreamingDataTemplate.liquid</stringProp>
            </com.microsoft.eventhubplugin.EventHubPlugin>
            <hashTree/>
            </hashTree>
        </hashTree>
        </hashTree>
    </jmeterTestPlan>
    

    com.microsoft.eventhubplugin.EventHubPluginGui および com.microsoft.eventhubplugin.EventHubPlugin の実装は、Azure Samples で入手できます。

  3. このファイル内で、eventHubConnectionVarName ノードの値を、Event Hubs 接続文字列のホストを指定する変数名に設定します。 たとえば、Event Hubs の接続文字列を格納する環境変数を EventHubConnectionString にする場合は、この変数を EventHubConnectionString に設定してから、この環境変数の値を設定します。

    重要

    ロード テスト スクリプトを実行する前に、Azure ロード テスト作成プロセスの一環として値 EventHubConnectionString が設定されていることを確認してください。

  4. このファイル内で、eventHubName ノードの値をイベント ハブ名 (telemetry-data-changed-eh など) に設定します。

  5. 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 }}
    }
    

    この例では、イベント ハブ メッセージのペイロードは、3 つのプロパティ MachineIdTemperatureHumidity が含まれる JSON オブジェクトです。MachineId は長さ 27 でランダムに生成された ID、Temperature および Humidity は 100 未満のランダムな整数です。 このファイルは、Liquid テンプレートの構文です。 Liquid テンプレートは、さまざまな Web 開発フレームワークで使用される一般的なテンプレート言語です。 Liquid テンプレートを使用すると、開発者は簡単に更新および変更できる動的コンテンツを作成できます。 これにより、変数、条件、ループ、およびその他の動的要素をイベント ハブ メッセージに挿入できます。 構文は簡単で、作業を開始するために役立つ豊富なオンライン リソースが用意されています。 総合的に見て、Liquid テンプレートは、動的でカスタマイズ可能なメッセージを作成するための強力かつ柔軟な手段として活用できます。

  6. ファイルを保存して閉じます。

    重要

    JMeter スクリプトのサンプラー名に個人データを含めないでください。 サンプラー名は、Azure Load Testing のテスト結果ダッシュボードに表示されます。 Liquid テンプレートのサンプルは、JMeter スクリプト ファイルと共に、Azure サンプルのページからダウンロードできます。

新しいプラグインを使用してロード テストを実行する

Azure Load Testing でロード テストを開始する場合、JMeter スクリプトと他のすべてのファイルがテスト エンジン インスタンスにデプロイされてから、ロード テストが開始されます (「Apache JMeter プラグインと Azure Load Testing を使用してロード テストをカスタマイズする」の手順を参照してください)。 テストを実行する前に、パラメーター タブに移動して EventHubConnectionString を定義し、接続文字列をイベント ハブに指定します。

Screenshot that shows the parameters of the test.

環境に応じたパフォーマンス テストのセットアップ

どのようなパフォーマンス テストにおいても、運用環境と同様の環境を使用することが重要になります。 ここでは、システムのキャパシティとパフォーマンスを理解しやすくするために、以下の環境をパフォーマンス テストに使用します。

サンプル アーキテクチャでは、以下に示すサービスをパフォーマンス テストに使用できます。

サービス 構成
Eventhub Premium 構成、PU (処理装置) x 1。
Azure 関数 Linux、Premium プラン (EP1) - 210 ACU、3.5 GB メモリ、vCPU x 1 相当の Standard_D1_v2
リージョン 米国東部

Event Hubs や Azure Functions など、Azure サービスに適したサービス レベルの選択は複雑なプロセスであり、多くの要因に左右されます。 詳細については、「Azure Event Hubs の価格」および「Azure Functions の価格」を参照してください。

パフォーマンス テスト用の KPI の設計

パフォーマンス テスト用の KPI (主要性能指標) を設計するには、事前にビジネス要件とシステム アーキテクチャの 2 つが必要になります。 ビジネス要件は、応答時間、スループット、エラー率など、どのような KPI を測定する必要があるのかを知るために必要な情報です。 システム アーキテクチャは、Web サーバー、データベース、API など、各コンポーネントのパフォーマンスをどのようにテストするのか、その方法を知るために必要な情報です。 この情報は、ロード テスト、ストレス テスト、耐久テストなど、最適なパフォーマンス テスト戦略を選択するためにも役立ちます。

この例でのビジネス要件は、次のとおりです。

  • システムが、1 秒あたり 1,000 件の要求を処理できること。
  • システムの信頼性が 0.99 を上回ること。
  • システムが、個人データ情報を報告する 1,000 台のコンカレント デバイスを処理できること。
  • システムの最大キャパシティ (何台のデバイスをサポートできるか) を指定すること。 たとえば、現在の 3 倍のキャパシティを持つシステムでは、1,000 台のコンカレント デバイスをサポートできるか、など。

これらの要件に従い、パフォーマンス テスト用として次のような KPI が考えられます。

KPI 説明
RPS イベント ハブに対する 1 秒あたりの要求数
LOAD パフォーマンス テスト中にイベント ハブに送信されたロードまたは要求の数
IR 関数の実行回数またはインジェスト率
RT Azure 関数の実行時間の平均
AMU Azure Functions でのメモリ平均使用量
SR すべての関数実行回数に対する成功率
ARS ダウンストリーム サービスの平均応答時間 (SQL サーバーやマイクロサービスなど)
DF 依存関係エラーの数 (内部 Azure 関数エラーを含む)
MRPS イベント ハブにバックログがない最大 RPS (システム キャパシティ)

KPI の測定方法

KPI を測定するには、パフォーマンス テスト戦略が必要になります。 この戦略では、各コンポーネントのパフォーマンス テスト アプローチを定義します。 この例では、以下のパフォーマンス テスト戦略を使用しています。

  • イベント ハブ: イベント ハブのパフォーマンス テスト アプローチは、イベント ハブに多数のメッセージを送信し、RPS と LOAD を測定することです。 RPS は、1 秒あたりにイベント ハブに送信されたメッセージの数です。 LOAD は、パフォーマンス テスト中にイベント ハブに送信されたメッセージの合計数です。 Azure Load Testing サービスでは、RPS と LOAD を測定できます。
  • Azure Functions: Azure Functions のパフォーマンス テスト アプローチは、以下のメトリックを測定することです。
    • IR は、関数の実行回数またはインジェスト率です。
    • RT は、Azure 関数の実行時間の平均です。
    • AMU は、Azure Functions でのメモリ平均使用量です。
    • SR は、すべての関数実行回数に対する成功率です。
    • ARS は、ダウンストリーム サービスの平均応答時間です。
    • DF は、内部 Azure 関数エラーを含む、依存関係エラーの数です。
    • Azure Monitor サービスでは AMU、ARS、DF を測定できますが、IR、RT、SR は測定できません。

Azure Monitor サービスを使用して KPI を測定するには、Azure Functions について Application Insights を有効にする必要があります。 詳細については、「Application Insights との統合を有効にする」を参照してください。

Azure Monitor サービスを有効にした後、以下のクエリを使用して KPI を測定できます。

  • IR: 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
  • SR: 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 Monitor ダッシュボードのサンプル

クエリに基づいて Azure Functions の KPI を示す Azure Monitor ダッシュボードのサンプルを以下に示します。

Screenshot samples of the Azure Monitor dashboard.

まとめ

この記事では、Azure Load Test 用に KPI を設計し、ダッシュボードを開発する方法について説明しました。 また、JMeter でカスタム プラグインを使用して、Event Hubs と統合された Azure Functions に対するロード テストを実行する方法についても学習しました。 同じ方法を使用して、他の Azure サービスについてロード テストを実行することもできます。 Azure DevOps を使用して、ロード テスト スクリプトに対する CI/CD (継続的インテグレーションおよび継続的デリバリー) パイプラインをセットアップすることもできます。

詳細については、Azure Load Testing のドキュメントを参照してください。

共同作成者

この記事は、Microsoft によって保守されています。 当初の寄稿者は以下のとおりです。

プリンシパル作成者:

  • Mahdi Setayesh | プリンシパル ソフトウェア エンジニア

パブリックでない LinkedIn プロファイルを表示するには、LinkedIn にサインインします。

次のステップ