Azure App Serviceプランにたくさんのアプリを詰め込む「高密度ホスティング」を試してみたTech TIPS

Azureの「App Serviceプラン」になるべく多くのApp Serviceを詰め込んで料金を節約しようとしたことはないだろうか? もしあるなら、「高密度ホスティング」が役に立つかもしれない。その設定方法や注意点を紹介する。

» 2025年05月22日 05時00分 公開
[島田広道デジタルアドバンテージ]
「Tech TIPS」のインデックス

連載目次

App Serviceプラン インスタンス App Service 2つに増える 空いた分、別のApp Serviceを詰め込める

対象:Azure App Serviceプラン、App Service


 Azureの「App Service」の料金を節約する方法の一つとして、「App Serviceプラン」になるべく多くのApp Serviceを詰め込むというものがある。App Serviceの料金は基本的にApp Serviceプランの性能とそのインスタンス数で決まるため、より多くのApp Serviceを詰め込むほど、App Service一つ当たりの料金を下げることができるからだ(もちろん詰め込み過ぎれば性能が下がってしまうが)。

 その点で注目したいのがApp Serviceプランの「高密度ホスティング」という機能だ。スケーリングを工夫することで、より多くのApp ServiceをApp Serviceプランに乗せることができるという。

 本Tech TIPSでは、App Service/プランを実際にデプロイしたことがある運用担当を対象として、この機能を実際に試しながら、その設定方法や注意点などを紹介する。

■執筆時の各種ツール/APIのバージョン


「高密度ホスティング」とは?

 「高密度ホスティング(high-density hosting)」とは、App Serviceごとにスケーリングの上限数を変える(アプリごとのスケーリングを有効にする)ことで、通常より多くのApp ServiceをApp Serviceプランに詰め込むことを指す。

 デフォルトの設定の場合、App Serviceのスケーリング数はApp Serviceプランのインスタンス数と一致する。App Serviceプランのインスタンス数を増やすと、そこで実行中の全App Serviceも、その分だけ下図のように増える。

デフォルト(アプリごとのスケーリングが無効)のApp Serviceプランのスケールアウト デフォルト(アプリごとのスケーリングが無効)のApp Serviceプランのスケールアウト
「アプリごとのスケーリングが無効」とは、全てのApp Serviceでスケーリング数がApp Serviceプランのインスタンス数と一致することを意味する。

 しかし、全てのApp Serviceで等しくスケールアウトが必要とは限らない。例えば、幾つかのApp Serviceでは負荷もアクセス数も大きく変動しないのでスケールアウトは不要(常に1つでよい)な一方で、他のApp Serviceはよくアクセスされるので2つ以上にスケールアウトさせたい、といった状況が考えられる。

 そこで、App Serviceごとにスケールアウトの上限数を別々に設定できるようにすると、インスタンス数を増やしてもスケールアウトしないApp Serviceがある分、インスタンスに余裕が生じる。下図のように同じインスタンス数でも、より多くのApp Serviceを詰め込めるようになる。

アプリごとのスケーリングが有効なApp Serviceプランのスケールアウトの例 アプリごとのスケーリングが有効なApp Serviceプランのスケールアウトの例
実際には、複数のインスタンスに対して均等にApp Serviceが分散配置されるとは限らない(詳細は後述)。

【ARMテンプレート】App Serviceごとにスケーリング上限数を変更できるようにするには

 App Serviceごとにスケーリング上限数を可変にするには、App ServiceプランとApp Serviceの両方で設定変更が必要になる。ただ、どちらもAzureポータルからは設定できない。ここではARM(Azure Resource Manager)テンプレートによる設定方法を説明する。

●App Serviceプランで「アプリごとのスケーリング」を有効化する

 まずApp Serviceプランについては、以下のリストのリソース「appServicePlan」にある「properties.perSiteScaling」に「true」を指定する(デフォルトはfalse)。

// ファイル: asp.azuredeploy.bicep

////////// App Serviceごとにスケーリング上限数を //////////
////////// 変更できるApp Serviceプランを作成する //////////

param appServicePlanName string // App Serviceプラン名
param location string = resourceGroup().location // 作成先のリージョン

@maxValue(30)
param baseCapacity int = 2 // デプロイ直後のインスタンス数

param skuName string = 'P1v3' // SKU名称。すぐ下の「skus」のキー名から選択
var skus = {
  // SKUの定義。Premium V3のみ
  P0v3: {
    name: 'P0v3'
    tier: 'PremiumV3'
    capacity: baseCapacity
  }
  P1v3: {
    name: 'P1v3'
    tier: 'PremiumV3'
    capacity: baseCapacity
  }
  P1mv3: {
    name: 'P1mv3'
    tier: 'PremiumV3'
    capacity: baseCapacity
  }
}

// リソース生成: App Serviceプラン
resource appServicePlan 'Microsoft.Web/serverfarms@2024-04-01' = {
  name: appServicePlanName
  location: location
  sku: skus[skuName]
  kind: 'linux' // OSはLinuxとする
  properties: {
    perSiteScaling: true // App Serviceごとにスケーリング上限数を変える
    reserved: true // Linuxを使用する場合はtrue(falseだとエラーで失敗する)
  }
}

【Bicep】App Serviceごとにスケーリング上限数を変更できるApp Serviceプランを新規作成する
※Microsoftのレファレンス: Microsoft.Web serverfarms

●App Serviceのスケーリング上限数を設定する

 次にApp Serviceを新規作成する際、以下のリストのパラメーター「numberOfWorkers」にスケーリング上限数を指定する。例えば、スケールアウトが不要なら「1」、4つまでスケールアウトさせたいなら「4」というように指定すること。

// ファイル: app.azuredeploy.bicep

////////// App Serviceのデプロイ時にスケーリング上限数を指定する //////////

param location string = resourceGroup().location
param siteName string // App Serviceの名前

param numberOfWorkers int = 1 // App Serviceのスケーリング上限数

// リソース生成: App Serviceのサイト本体
resource webApp 'Microsoft.Web/sites@2024-04-01' = {
  name: siteName
  location: location
  properties: { /* ……<省略>…… */ }
}

// リソース生成: App ServiceのWeb設定
resource webAppConfig 'Microsoft.Web/sites/config@2024-04-01' = {
  parent: webApp
  name: 'web' // 必ず「web」を指定
  properties: {
    // ……<省略>……
    numberOfWorkers: numberOfWorkers
    // ……<省略>……
  }
}

【Bicep】App Serviceの新規作成時にスケーリング上限数を指定する
※Microsoftのレファレンス: Microsoft.Web sites/configMicrosoft.Web sites

 上記の設定は、「アプリごとのスケーリング」を有効化したApp Serviceプラン上の全App Serviceに対して個別に実行する必要がある。

【PowerShell】App Serviceごとにスケーリング上限数を変更できるようにするには

 既存のApp Serviceプラン/App Serviceでも、デプロイし直すことなくスケーリング上限数を可変にできる。ここではAzure PowerShellによる設定方法を説明する。

●App Serviceプランで「アプリごとのスケーリング」を有効化する

 まずApp Serviceプランについては、「Set-AzAppServicePlan」コマンドレットに「-PerSiteScaling $true」というオプションを指定して実行する。

Set-AzAppServicePlan -ResourceGroupName <App Serviceプランのリソースグループ名> -Name <App Serviceプランのリソース名> -PerSiteScaling $true


 設定できたかどうかを確認するには、「Get-AzAppServicePlan」コマンドレットを利用する。

(Get-AzAppServicePlan -ResourceGroupName <App Serviceプランのリソースグループ名> -Name <App Serviceプランのリソース名>).PerSiteScaling


●App Serviceのスケーリング上限数を設定する

 次にApp Serviceについては、「Get-AzWebApp」「Set-AzWebApp」コマンドレットを使って、「SiteConfig.NumberOfWorkers」にスケーリング上限数を指定する。

$app = Get-AzWebApp -ResourceGroupName <App Serviceのリソースグループ名> -Name <App Serviceのリソース名>
$app.SiteConfig.NumberOfWorkers = <スケーリング上限数>
Set-AzWebApp $app


 また、スケーリング上限数を確認するには以下のコマンドラインを実行する。

(Get-AzWebApp -ResourceGroupName <App Serviceのリソースグループ名> -Name <App Serviceのリソース名>).SiteConfig.NumberOfWorkers


App Serviceの「現在」のスケーリング数は確認できない!?

 App Serviceごとのスケーリング上限数を可変にすると、当然ながらApp Serviceプランのインスタンス数とApp Serviceのスケーリング数が一致しなくなる。例えばインスタンス数が2つ以上でも、スケーリング上限数を「1」に設定したApp Serviceは、スケーリング数は「1」になる。また、スケーリング上限数を「3」にしたApp Serviceでも、インスタンス数が2つの場合、スケーリング数は「2」のはずだ。

 こうなると、各App Serviceが「現在」どれくらいスケーリングされているか、その数を確認したくなる。

 ところが、筆者が調べた限りでは、この「現在」のスケーリング数を簡単に確認する方法を見つけられなかった。唯一、App Serviceが出力するログ「HTTP logs」(いわゆるアクセスログ)に含まれる「ComputerName」カラムに現れる各インスタンスのコンピュータ名の個数でスケーリング数を推定できそうだ。

 Azureのログ分析サービス「Log Analytics」がApp Serviceに対してセットアップ済みの場合、以下のクエリを実行すると、クライアントからのリクエストを受け付けたインスタンスのコンピュータ名が一覧表示される。直近のアクセス数(以下のリストや画面にある「RequestCount」)がおおよそ均等なら、コンピュータ名の数がApp Serviceの「現在」のスケーリング数と推定できる。

// インスタンスごとにアクセス数を集計して、スケーリング数を推定する
AppServiceHTTPLogs
| where CsHost !endswith ".scm.azurewebsites.net" // 高度なサイトは除外
| summarize RequestCount = count() by ComputerName
| order by ComputerName



インスタンスごとのアクセス数を集計した結果 インスタンスごとのアクセス数を集計した結果
3つのコンピュータ名=3つのインスタンスにアクセスが分散している、つまりスケーリング数は「3」と推定できる。

【実験】「高密度ホスティング」を実際に試してみた

 ここまで説明した方法で実際に「アプリごとのスケーリング」を有効にしたApp Serviceプランとスケーリング上限数が異なる複数のApp Serviceをデプロイし、インスタンス数を増減させながら、各App Serviceがどのように配置されるのか試してみた。

 その結果を以下に図示する。「n=1」と記しているアイコンは、「スケーリング上限数が1のApp Service」を表している。

1.1つのインスタンスをデプロイ 1.1つのインスタンスをデプロイ
インスタンスが1つだけなので、どのApp Serviceもスケーリング数は1つに留まった。
2.インスタンス数を計2つに増加 2.インスタンス数を計2つに増加
スケーリング上限数が2つ以上のApp Serviceはインスタンス数と同じだけスケールアウトした。その一方で、上限数が1つのものはスケールアウトしなかった。
3.インスタンス数を計3つに増加 3.インスタンス数を計3つに増加
スケーリング上限数が3つのApp Serviceは、3つにスケールアウトした。一方、上限数が2つ以下のApp Serviceには変化がなかった。
4.n=1のApp Serviceを複数追加 4.n=1のApp Serviceを複数追加
スケーリング上限数をインスタンス数より少ない「1」に設定したApp Serviceをどんどん追加していったところ、インスタンス3は多め、インスタンス2は少なめ、というようにApp Serviceの密度に偏りが生じた。
5.インスタンス数を計2つに削減 5.インスタンス数を計2つに削減
3つのインスタンスのうち、最もApp Serviceの少なかったインスタンス2が削除された。その一方でApp Serviceは再配置されず、密度の偏りは変わらないままだった。
6.インスタンス3のn=1のApp Serviceを削除して再作成 6.インスタンス3のn=1のApp Serviceを削除して再作成
既存のApp Serviceが少ない方のインスタンス1に、再作成したApp Serviceが追加された。これにより密度の比率は4対7から5対6と均等に近づいた。

 図「4.n=1のアプリを複数追加」のように、上限数が「1」のApp Serviceを複数追加したところ、各インスタンスへ均等には配分されず、インスタンスごとに密度の偏りが生じた。これはMicrosoftが公開しているドキュメントに「均等な配分は保証されていない」と記されているとおりの挙動といえる。

 一方、上限数が2つ以上のApp Serviceについては、インスタンス数が足りていれば、各インスタンスへ均等にスケールアウトされた。これもMicrosoftのドキュメントの通りである。

 また、図「6.インスタンス3のn=1のApp Serviceを削除して再作成」の挙動からすると、密度の偏りが生じたら、いったんApp Serviceを削除して再作成すると、均等な配置に近づけられそうだ。

【注意】「アプリごとのスケーリング」が有効だと「自動」のスケールアウトが選択できない

 App Serviceプランで「アプリごとのスケーリング」を有効にした場合、スケールアウトの方法に制約が生じる。

 具体的には、AzureポータルでApp Serviceプランのページを開き、[設定]−[スケールアウト(App Serviceのプラン)]を選択すると表示されるスケールアウトの設定ページで、「スケールアウト方法」欄の[自動](トラフィックに基づくプラットフォームマネージドスケールアップとスケールダウン)というラジオボタンがグレーアウトして選択できない。

「アプリごとのスケーリング」が有効な場合に選択できないスケールアウト方法 「アプリごとのスケーリング」が有効な場合に選択できないスケールアウト方法

 このスケールアウト方法をどうしても使いたい場合、執筆時点では「アプリごとのスケーリング」を無効にするしかないようだ。

「Tech TIPS」のインデックス

Tech TIPS

Copyright© Digital Advantage Corp. All Rights Reserved.

アイティメディアからのお知らせ

スポンサーからのお知らせPR

注目のテーマ

4AI by @IT - AIを作り、動かし、守り、生かす
Microsoft & Windows最前線2025
AI for エンジニアリング
ローコード/ノーコード セントラル by @IT - ITエンジニアがビジネスの中心で活躍する組織へ
Cloud Native Central by @IT - スケーラブルな能力を組織に
システム開発ノウハウ 【発注ナビ】PR
あなたにおすすめの記事PR

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。