この記事はAzure DevOpsアドベントカレンダー12日目の記事です。
Azure Load Testingについて
先日、Azure Load Testingという新しいサービスがプレビュー公開されました。はっきり言ってしまえばJMeterのマネージドサービスです。
あれ、Azure DevOpsにもLoad Testがあったよね?と思われるかもしれませんが、ありました。そして2020/3/31にディスコンになりました。
Visual Studioと統合されていて、VSのロードテスト機能からも使えて便利だったのですが引退してしまい、ちょっと困っていました。何回か紹介したことがあります。
今ではほかのマネージドサービスを使うか、pnopさんが出しているカスタムイメージ使うか、というくらいでしたが、新しいオプションとして選択できそうです。
ちょっと試してみましょう。注意事項としてjmxファイルの内容(サンプラー名やコントローラー名といったメタデータ)は英語で書きましょう。最初日本語で書いていてLoad TestがAcceptedのままずーっと動かなくて悩みました。もしかして、と思って英語に変えたらあっさり動きました。JmeterのUIを日本語にすると自動的に日本語のメタデータが入っていしまうので、英語で使うことをお勧めします。
そういえばAzure DevOps Load Testのときも同じことで悩んでいたような…。jmeterのインストールはchocolateyやmacOSの場合はHomeBrewでできるので省略(いまだにJRE 8をペアで入れさせられるのには閉口しますが…)。そういえば、macOSでjmeterのファイル保存できないのLook & Feelを変えないといけないって誰が気付くんだ。
ポータルから作成する
ポータルから作成します。
サブスクリプション、名前、リージョンを設定します。今のところ限られたリージョンだけですが、米国中南部を選んでみます。Load Testingの枠としてはこれだけなのですぐ作成すればOKです。
ポータルからテストを実行する
Test Plan, Parameter(実行時パラメータ), テスト合格基準、モニタリングなどポータルから設定します。
テスト名は任意。Run after creation
にチェックがあるとすぐに実行されます。
ここで作っておいたjmxファイルをアップロードします。くれぐれもリスナー名やクライアント名に日本語を使わないようにしましょう(重要なことなので繰り返し)。
実行時パラメータがあれば指定します。
実行エンジン数を指定します。4を指定すれば1000スレッドまでかけられるようですね。jmxでは250スレッドまでなので、それをいくつの実行エンジンでスケールするかということのようです。
ここでエラー基準を決めます。注意事項としてWeb Appsのお安い(FとかDとか)インスタンスではウォームアップの時間が必要になるので、ここにあるように応答時間(Response Time)に100msなどの短い時間を指定していると初回実行が間に合わなくて失敗します。
モニタリングするリソースを選択します。
作成したら即実行が始まります。
こんな感じで結果が見えます。failedになっているのは上で書いた通り実験用の環境でWeb Appsのウォームアップが間に合ってないからです😅。実行には気を付けて。さて、CI/CDで実行するための準備をします。
CI/CDのためにロール割り当てを設定する
Azure Load Testingはプレビューだからか作っただけではAzure Pipelinesから呼び出せません。ロール割り当てをします。
いつものようにService Connectionを作成して、Azure Load Testingのリソースグループを割り当てます。Manage Service Principal
をクリックしてアプリケーションを表示して、アプリケーション表示名をコピペします。
Load Testing Contributorにアプリ追加します。
こんな感じで割り当て終わりです。
Azure Pipelinesから呼び出す。
Marketplaceからタスクを追加します。実行する前に以下の二つをどこかのレポジトリにコミットしておかなくてはなりません。
- Azure Load Testingを実行するテストケースを記述したYAMLファイル
- JMeterのjmxファイル
アプリケーション外部のレポジトリでもいいですし、一緒でもいいでしょう。ただし、「Webアプリケーションはこういう基準で動かなければならない」ということが品質のルールで決められているとしたらレビューする人たちにも参照可能な外部レポジトリを用意しておくのがいいかもしれませんね。
jmxファイルも同様です。
サンプルのAzure Load Testing実行するためのYAMLです。
version: v0.1 testName: SampleTest testPlan: sample1.jmx description: 'Load test website home page' engineInstances: 1 failureCriteria: - avg(response_time_ms) > 300 - percentage(error) > 50
CSVでパラメータ指定も可能です。testPlanにはこのYAMLから参照可能なパスで指定してください。ここでは同じフォルダーにダウンロードしているのでパス指定はありません。
YAMLで実行するステージを切り出すとこんな感じですね。
- stage: dependsOn: Deploy condition: succeeded() jobs: - job: LoadTest pool: vmImage: 'Ubuntu-latest' steps: - task: DownloadBuildArtifacts@0 displayName: 'Download Artifact' inputs: buildType: 'current' downloadType: 'single' artifactName: 'myWebsiteName' downloadPath: '$(System.ArtifactsDirectory)' - task: AzureLoadTest@1 inputs: azureSubscription: '{サービス接続名}' loadTestConfigFile: '$(System.ArtifactsDirectory)/myWebsiteName/azure-load-testing.yml' resourceGroup: '{リソースグループ名}' loadTestResource: '{ロードテスト名}' - publish: $(System.DefaultWorkingDirectory)/loadTest artifact: results
ここでは明示的に別ステージにしています。通常デプロイが成功したらこの手のテストを実行するので、dependsOn
にデプロイ用のステージを指定して、condition
でsucceeded()
を指定しています。
なぜDownloadBuildArtifacts
タスクがあるのかと思うかもしれませんが、ステージが異なるとartifactの参照ができません。明示的にダウンロードしてくる必要があります。なので、YAMLとjmxはCopyFiles
タスクでBuild.ArtifactStagingDirectory
にコピーして、PublishBuildArtifacts
タスクで発行しなくてはなりません。デプロイされるアプリケーションとは別のartifactsにしておく方が望ましいかもしれませんし、同じテストを繰り返すという意味では一緒のほうがいいかもしれません。ここはお好みですかね。
最後のpublish: $(System.DefaultWorkingDirectory)/loadTest
でテスト結果を発行しています。
成功するとこんな感じですね。ログにhttpの応答時間や、View the load test run in progress at
でAzureポータルのリンクが出ているのでワンクリックで結果が見えます。
ポータルと同じようにYAMLに設定したfailureCriteria
が満たせない場合、ビルドが失敗したと表示されます。
Azureポータルでもこんな風に失敗となります。
注意事項
- Public InternetにあるURLに対して実施するものなので、閉域にあるサービスに対してはかけられません。JMeterのカスタムイメージ使いましょう。
- jmxは英語で書きましょう
- 実施可能なデータセンターの場所が限られていますので、応答時間気にするサービスで日本になくてはならないものだとちょっと注意が必要です。
- YAMLのステージ分割は必須になる
- YAMLとjmxをレポジトリに入れて、artifactsとしておくのを忘れずに