掲載内容は個人の見解であり、所属する企業を代表するものではありません.
早いもので Azure DevOps の Cloud-based load testing サービスが終了して 2 年が経ち、いつか Azure Load Testing も試してみようと思いながらも後回しにしてきたのですが、 やっと挑戦してみる気になりました。 まだプレビュー段階なのか・・・、と思いつつも試してみた、という記事です。以下は参考資料。
なお本記事の執筆時点ではまだプレビュー中のサービスであるため、今後変更になる可能性があります。
一般的には大規模な性能テストや負荷テストをやろうとすれば、以下のような手間がかかります。 これはおそらくどんなテストフレームワークを使ったとしても変わらないのではないでしょうか。 ただこれ、「テストスクリプトの開発」と「収集したデータの分析」以外はテスト対象システムに依存しないルーチンワークですよね。
Azure Load Testing は JMeter スクリプトを多数のマシンから並列実行させるサービスになっていて、上記の作業でルーチン化できる部分をサービスとして提供します。 負荷をかけるためのクライアントマシンを大量にセットアップしたり、データ収集する手間を削減できるので、従来と同じテストを行うにしてもエンジニアの工数が節約できます。 そうやって節約した時間とコストは、エンジニアが本来のお仕事である「テストスクリプトの開発」及び「データの分析」に注力することで、より高度なテストとシステム品質の改善に活用できるわけです。 またクラウドのキャパシティを活用することで、従来オンプレミス環境では現実的でなかった大規模な負荷を生成できるというのも大きいですね。
もちろんこの世の全ての負荷テストが Azure Load Testing (以下ALT)で実現できるわけではないですが、どんな機能が使えるのかを知っておいて、必要になった時の選択肢として持っておくと良いのではないでしょうか。
さてそれでは性能テストを実施する環境を準備していきます。大きく分けて3つです。
Test Engine
はテストを実施する際に動的に用意され、テストが終われば削除されますので管理の手間はかかりませんまずは作業マシンを用意していきます。
とりあえず動作検証するためにはローカルで動く Web アプリがあった方がいいので、私の愛する ASP.NET Core な Web アプリを作成しておきます。 こちらから .NET SDK をダウンロードしてインストールし、下記のコマンドで Web アプリの出来上がりです。
dotnet new webapp -o testapp01
cd tetapp01
dotnet run
info: Microsoft.Hosting.Lifetime[14]
Now listening on: https://localhost:7251
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://localhost:5049
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
Content root path: C:\Users\ayumu\Desktop\testapp01\
表示された localhost な URL をブラウザで開いて動作確認します。
JMeter の実行には Java が必要なのでインストールしていきます。 私は特にこだわりはないので Microsoft Build of OpenJDK からダウンロードしてインストールしました。
> java.exe --version
openjdk 17.0.3 2022-04-19 LTS
OpenJDK Runtime Environment Microsoft-32931 (build 17.0.3+7-LTS)
OpenJDK 64-Bit Server VM Microsoft-32931 (build 17.0.3+7-LTS, mixed mode, sharing)
次に本題の JMeter を Apache JMeter 本家のサイト から zip ファイルをダウンロードし、解凍したら中に入っている jmeter.bat
を起動するとユーザーインタフェースが立ち上がってきます。
が、この後の手順で発生するのですが、インストール直後に設定されている Darklaf
系のテーマが設定されていると、以下の様な警告が出てしまってファイルが保存できません。
2022-05-16 05:39:31,346 ERROR o.a.j.JMeter: Uncaught exception in thread Thread[AWT-EventQueue-0,6,main]
java.lang.IllegalAccessError: class com.github.weisj.darklaf.ui.filechooser.DarkFilePaneUIBridge$DetailsTableModel (in unnamed module @0x15761df8) cannot access class sun.awt.shell.ShellFolder (in module java.desktop) because module java.desktop does not export sun.awt.shell to unnamed module @0x15761df8
このエラーは Options > Look and Feel
から Darkloaf のつかない別のテーマを選択することで回避できます。
テーマを切り替えたら JMeter を再起動してください。
下記は Metal
テーマが適用されたユーザーインタフェースです。
それでは早速ローカルで動作している、先ほど開発した Web アプリ に負荷をかけてみましょう。 (筆者はこれが初めての JMeter なのでここはあまり深入りしていませんが、各種 Web の記事なり書籍なりをご参考にしてください)
http
、Server Name or IP は localhost
、ポートは Web アプリ起動時に表示されていた値を設定するGET
メソッドと Path /Index
を設定する準備が出来たら Start ボタンを押すことでテストが開始され、完了すると Listener 画面で結果が表示されます。
負荷がかかることが確認できたらテストプランを JMeter スクリプト(JMX ファイル)として保存して Azure Load Testing にアップロードするのですが、 テスト対象の URL がローカルに作成した Web アプリ(http://localhost:5049)を指示しているので、このままでは正常にテストができません。 このため実行環境に合わせて書き換えられるように、スクリプトに含まれる一部の設定値をパラメータ化しておく必要があります。
Azure Load Testing では実行時に シークレットと環境変数 を設定できますが、今回は機微情報を扱わないので環境変数を利用します。 各設定個所から直接環境変数を参照しても良いのですが、環境変数を読み取る構文が若干長いので、一度ユーザー定義変数に読み込んでおくとメンテがしやすくなります。
この状態でテストを実行してエラーが出ないことを確認しておき、JMeter スクリプト(JMX ファイル)として保存します。
さてやっと本題です。
Azure Load Testing を Azure Portal から作成しますが、最初はほぼ既定の設定で問題ないでしょう。 なお、まだ選択できるリージョンが少ないことにご注意ください。 テスト対象サービスが別リージョンの場合にはレスポンスタイムにオーバーヘッドが発生しますし、ネットワーク使用料も関わってきます。
おおむね1分程度で作成が完了します。必要なときにサクッとテスト環境が準備できるのは素敵です。
出来上がった Azure Laod Testing にテストを作成します。
まず Tesing
メニューを選択して Create test
を押すと、ウィザード形式でテストを作成できます。
Run test after creation
のチェックを外しておかないと、作成直後にいきなりテストが走りますAverage Response time (msec)
と Error (%)
の 2 つで、条件もgrater than
のみが指定できますテスト対象の Web アプリがインターネット越しにアクセスできることを確認しておき、
作成したテストを開いて Run
ボタンを押すとテストが実行できます。
すると Status が Provisioning -> Executing -> Done
と遷移してテスト結果が表示されます。
下記は JMX ファイル内のスレッドを 10 に、Engine Instance 数を 3 に設定した場合のテスト結果になります。
前述の Run ボタンを押せば同じ条件で何度でもテストを実行できます。 対象システムのスケールアウト(イン)や、スケールアップ(ダウン)で必要十分な性能になるようにチューニングしていきましょう。 気軽にリグレッションテストが出来るのはいいですね。
あるいは、テストの諸条件を変更したい場合には、テスト作成時の画面まで戻り Configure メニューから設定を変更するか、JMX ファイルを書き換えて再アップロードすることが出来ます。
私は JMX ファイルの定義で 100 スレッド設定にしていたせいか、テストエンジンが最小の 1 でも負荷がかかりすぎたので、負荷を下げる羽目になりました。
ここまでの内容でAzure Load Testing を使って負荷をかけることが出来ましたが、ここで得られるのは負荷の条件(= Virtual Users)に対してテスト対象システムの外部から見たメトリックにとどまります。
これらは代表的な性能指標値ではありますが、パフォーマンスチューニング、ボトルネックの特定、高負荷時の内部エラー情報の取得などを行うためには、テスト対象システムの内部から見たメトリックも必要になるでしょう。
さて対象システムが Azure Load Testing の対応する Azure リソースで構成されていれば、Azure Load Testing は Azure Monitor と連携して対象システムのメトリックも取得することが出来ます。 テスト対象が Web App や SQL Database の場合は、テスト設定の Monitoring タブにて対象リソースを追加することが可能です。
この状態でテストを実行するとクライアント側(Azure Load Testing 側)で計測されたメトリックと一緒にサーバー側(Azure で動作するテスト対象システム側)のメトリックを確認できます。
平均の応答時間とエラー率からこのテスト自体が成功、すなわち品質評価に合格だったことはわかりますが、サーバーサイドのメトリックからは以下の内容が確認できます。
参照したいメトリックは Configure metrics
で調整できますので、必要な項目を設定してください。
私自身は JMeter をこれまで全く扱ってこなかったのですが、慣れている方であれば割と簡単に使いこなせるのではないでしょうか。 現状では VNET 内に配置されているシステムなど、インターネットからアクセス出来ないタイプの Web システムに使用できないのが残念なところです。 まだプレビューということで今後に期待していきたいと思います。