はじめに
この記事では Azure App Service における、Automatic Scaling(自動スケーリング)の動作を確認します。
https://learn.microsoft.com/ja-jp/azure/app-service/manage-automatic-scaling?tabs=azure-portal
名前が分かりにくいですが、従来からある Azure Monitor でのAutoScale(自動スケーリング)とは異なり、App Service 独自の仕組みとなります。
どういった条件でスケーリングが発生しうるのかなどを確認していきます。
どういった仕組か
ドキュメントには以下の記述があります。
自動スケーリングはバックグラウンドでどのように機能していますか?
自動的にスケーリングするように設定されたアプリケーションは継続的に監視され、少なくとも数秒に 1 回は作業者の正常性を評価します。 システムがアプリケーションの負荷増加を検出すると、正常性チェックの頻度が高くなります。 作業者の正常性状態が悪化し、ペースダウンが要求された場合は、追加のインスタンスが要求されます。 インスタンスが追加される速度は、個々のアプリケーションの負荷パターンと起動時間によって異なります。 起動時間が短く、断続的に負荷が発生するアプリケーションでは、数秒から 1 分ごとに 1 台の仮想マシンが追加されるのを確認できます。負荷が落ち着くと、プラットフォームでスケーリングの可能性を確認し始めます。 このプロセスは通常、負荷の増加が止まってから約 5 - 10 分後に開始します。 スケールイン中、インスタンスは最大で数秒から 1 分に 1 つの割合で削除されます。
AppServiceHTTPLogs に 404 状態を含む "/admin/host/ping" のようなログ エントリがあるのはなぜですか?
App Service の自動スケーリングは、プラットフォーム固有の他の正常性チェック メカニズムとともに、/admin/host/ping エンドポイントを定期的にチェックします。 これらのチェックは特別に実装された機能です。
検証
事前準備
用意した環境は以下の通り
- OS : Linux
- SKU : P0v3
- 最大バースト: 4
まずは、前述 Doc に記載の /admin/host/ping
へのリクエストの状態を確認してみます。
はい。/admin/host/ping
へのリクエストはありません。
その代わり? 13 秒毎に UserAgent ElasticScaleControllerExtension/2.0.29.0
からの /
に対するリクエストがAutomatic Scalingを有効にしたタイミングから始まっています。
また、同一 App Service Plan にデプロイされているほかの App Service に対しても当該のリクエストが行われていることが確認できます。
実験 1 /
を遅くしてみる
他にアクセスがないからか、単純に ElasticScaleControllerExtension/2.0.29.0
からのリクエストの応答速度だけをもとにスケールするわけではなさそうです。
実験 2 リクエスト数を増やす
/
の応答遅延をなくしてリクエスト数を増やしてみます。
ベースとなるのは以下の k6 スクリプト。単純に1秒おきに /
にアクセスを繰り返します。
負荷1
まずは 10 vus(秒間10Req/s 600req/min)
k6 run -u 0 -s 30s:10 -s 120s:10 -s 30s:0 ./test.js
http_reqs......................: 1272 7.023404/s
iteration_duration.............: avg=1.18s min=1.15s med=1.16s max=1.96s p(90)=1.21s p(95)=1.24s
iterations.....................: 1272 7.023404/s
vus............................: 1 min=0 max=10
vus_max........................: 10 min=10 max=10
running (3m01.1s), 00/10 VUs, 1272 complete and 0 interrupted iterations
default ✓ [======================================] 00/10 VUs 3m0s
結果、変化なし
負荷2
負荷1の10倍で試してみる 100 vus(秒間100Req/s 6000req/min)
k6 run -u 0 -s 30s:100 -s 120s:100 -s 30s:0 ./test.js
http_reqs......................: 12778 70.56061/s
iteration_duration.............: avg=1.17s min=1.15s med=1.16s max=2.67s p(90)=1.18s p(95)=1.22s
iterations.....................: 12778 70.56061/s
vus............................: 1 min=1 max=100
vus_max........................: 100 min=100 max=100
running (3m01.1s), 000/100 VUs, 12778 complete and 0 interrupted iterations
default ✓ [======================================] 000/100 VUs 3m0s
結果、変化なし
負荷3
負荷の期間を長くしてみる
k6 run -u 0 -s 30s:100 -s 300s:100 -s 30s:0 ./test.js
http_reqs......................: 28315 78.533468/s
iteration_duration.............: avg=1.16s min=1.15s med=1.16s max=2.17s p(90)=1.17s p(95)=1.18s
iterations.....................: 28315 78.533468/s
vus............................: 3 min=3 max=100
vus_max........................: 100 min=100 max=100
running (6m00.5s), 000/100 VUs, 28315 complete and 0 interrupted iterations
default ✓ [======================================] 000/100 VUs 6m0s
結果、変化なし
これはリクエスト数が増えてもそもそも応答が早く返せているからなのか?
負荷4
負荷1の100倍にしてみる 1000 vus(秒間1000Req/s 60000req/min)
k6 run -u 0 -s 30s:1000 -s 120s:1000 -s 30s:0 ./test.js
http_reqs......................: 107087 592.268191/s
iteration_duration.............: avg=1.4s min=1.15s med=1.16s max=28.18s p(90)=1.67s p(95)=2.08s
iterations.....................: 107087 592.268191/s
vus............................: 1 min=1 max=1000
vus_max........................: 1000 min=1000 max=1000
running (3m00.8s), 0000/1000 VUs, 107087 complete and 0 interrupted iterations
default ✓ [======================================] 0000/1000 VUs 3m0s
閾値に設定した4までスケールアウトしたことが確認できた。
スケールアウトできないといった問題があるというわけではなさそうなので、今後パターンを変えて様子を探っていきます。