Azure App Service の 2 種類の Auto-heal 機能について (Custom Auto-heal と Proactive Auto-heal)

本ブログでは Azure App Service の Auto-heal 機能について詳細に記載します。App Service の問題の解決と診断ブレードで設定可能な回復機能です。

# Auto-heal 機能
Auto heal は、一般的には Webアプリケーションが特定の問題を抱えているときに、自動的に修復処理を実行する機能 (自動復旧・回復・修復機能) です。

具体的には、Azure App Service (Azure Web Apps) では、アプリケーションが一定の条件 (要求数、遅い要求、メモリ制限、および HTTP ステータス コードに基づいて独自のルールを設定) を満たすと、自動的に設定したアクションを実行します。例えば、アプリケーションを再起動したり、カスタムの診断ツールを実行したりします。

Azure App Service の Autoheal は 2 つの種類があり、カスタムで設定する Auto-heal と Proactive Auto-heal 機能があります。

## A. Auto-heal 機能 (Custom Auto-Heal Rules)
Auto-heal 機能の設定は、Azure ポータル上の Diagnose and solve problems
 (問題の診断と解決 ブレード) から行うことができます。具体的には、「Diagnose and solve problems」ページから、「Auto-Heal」を検索し、設定を行います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/a57109af-00a3-a3fe-52a8-692a1a064afd.png)

例えば、HTTP ステータスコードを基に Auto-heal を設定する場合、HTTPステータスコードの範囲（例：400～499）、時間間隔（例：5分）、および発生回数（例：10回） などを指定します。これにより、特定のHTTPステータスコードが一定時間内に一定数以上返された場合に、Auto-heal が発動します。Custom Auto-heal の設定は大きく分けて 3 つのステップで行います。

### 1. 条件の定義

まず、Auto-healが発動する条件を定義します。これには以下のような項目があります。

- **リクエスト時間**: リクエストが特定の時間以上かかった場合
- **メモリ使用量**: メモリ使用量が特定の閾値を超えた場合
- **リクエスト数**: 一定時間内にリクエストが特定の数を超えた場合
- **HTTPステータスコード**: 特定のHTTPステータスコードが一定数以上返された場合

#### 条件の詳細について

- **リクエスト時間**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/7240de9c-4579-2b57-3b5b-45070889a0ed.png)
トリガーするカウント数・リクエストの最小継続時間 （秒）・時間間隔 （秒）・リクエストのパス （すべてのリクエストの場合は空白）

- **メモリ使用量**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/2b87d26d-b234-0056-8562-ef1878c80830.png)
設定したいメモリの閾値 （プライベートバイト） （KB）

- **リクエスト数**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/3139ed77-7b9a-234b-dcac-6114701490ae.png)
トリガーするカウント数・時間間隔 （秒）

- **HTTPステータスコード**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/020ff93e-fba4-c604-9908-8d1b16a24585.png)
トリガーするリクエスト数・ステータスコード・サブステータスコード・win32-status コード・時間間隔 （秒）・リクエストのパス （すべてのリクエストの場合は空白）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/65be24ed-4340-8c84-dbb5-aea1bfb42f5d.png)
トリガーするリクエスト数・ステータスコードの範囲・時間間隔 （秒）・リクエストのパス （すべてのリクエストの場合は空白）

### 2. アクションの設定

次に、条件が満たされたときにどのようなアクションを実行するかを設定します。アクションは以下の3つから選ぶことができます。

- **プロセスの再起動**: 問題が発生したプロセスを再起動します。この再起動は独立したもので、他のプロセスやアプリケーション全体の動作には影響しません。
- **ログの記録**: 問題が発生したときにログを記録します。これにより、問題の原因を特定しやすくなります。
- **カスタム アクション**: 自分で定義したアクションを実行します。これには、診断ツールの実行や任意の実行可能ファイルの実行などが含まれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/4f063fae-3816-26cf-2839-e4cf682f887c.png)


#### カスタムアクションについて
Custom Auto-heal のカスタムアクションは、「Run Diagnostics」と「Run Any Executable」の2つの種類があります。

##### Run Diagnostics
「Run Diagnostics」は、問題の診断を行うための機能で、以下の5つの種類があります：

- Memory Dump ： メモリダンプを取得します。これは、プロセスのメモリ使用状況を詳細に調査するためのものです。
- CLR Profiler ： CLR プロファイラトレースを取得します。これは、ASP.NET アプリケーションのパフォーマンスを詳細に調査するために利用できます。
- CLR Profiler with Thread Stacks ： .NETプロファイラのトレースとスタックをダンプしたものを取得します。これも .NETアプリケーションのパフォーマンスを詳細に調査するために利用できます。
- Java Memory Dump : Webアプリで実行されているすべての java.exe プロセスのjMap を使用したバイナリメモリーダンプを収集します。
- Java Thread Dump : このアプリのために実行されているすべての java.exe プロセスの jStack 出力を収集し、分析します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/cf661efc-b30b-5ddf-6d5d-cc6fcf2e3044.png)

また、「Tool Options」では以下の3種類を設定できます：

- CollectKillAnalyze ： 問題の診断情報を収集した後、プロセスを終了します。
- CollectLogs ： 問題の診断情報を収集し、ログを取得します。このオプションを選択すると、上記で選択したツールのデータのみが収集されます。解析は行われず、プロセスは再起動されません。
- Troubleshoot ： 上記で選択されたツールのデータを収集し、その後分析します。この場合、プロセスは再起動されません。

※ CollectLogs と Troubleshootについて、プロセスを再起動しないツールオプションのため、自動回復アクションが複数回実行され、大量のデータが生成される可能性があるので注意が必要です。Portal によると、データ収集後にプロセスが再起動されるように、CollectKillAnalyzeオプションを選択することを推奨とのことです。

##### Run Any Executable

「Run Any Executable」では任意の実行可能ファイルを実行するための機能です。これにより、自分で作成したスクリプトなどを実行し、独自の診断や修復処理を行うことが可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/b0d3a91e-7a30-97a2-727e-ee5039e93dcc.png)


### 3. アクションの実行タイミングの上書き （任意）

最後に、Auto-heal アクションが実行されるまでの最小時間を上書きするオプションもあります。プロセス起動後、自動回復を開始するまでの時間（秒）を指定します。これはアプリケーションの起動時間が長い場合に役立ちます。つまり、アプリケーションの起動中に自動修復のアクションが実行されないようにするための設定です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/cf7cfa8d-9cf1-0f44-d40c-eccdf3da72ce.png)


## B. Proactive Auto-heal 機能

### 概要
Proactive Auto-heal 機能では、App Service が復旧不可能な状態かを自動的に判断し、プロアクティブに自動復旧を行い、アプリを再起動します。

既定で、この機能は有効になっており、Custom Auto-Heal と同じ場所で、Azure ポータル上の Diagnose and solve problems (問題の診断と解決ブレード) から設定を変更することができます。(“WEBSITE_PROACTIVE_AUTOHEAL_ENABLED” という構成のアプリケーション設定で false にすることで無効化することもできます)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/1b85725d-b2e7-de6a-2ab0-6433b4adf209.png)

プロアクティブオートヒールでは、複数のインスタンスがある場合は、復旧必要な状態にあると判断されたインスタンスだけが再起動されます。なお、すべてのサイトで自動的に有効になりますが、すでに設定されている Auto-heal ルールが優先されると以下にも記載があります。

[Azure App Service Team Blog - Introducing Proactive Auto Heal](https://azure.github.io/AppService/2017/08/17/Introducing-Proactive-Auto-Heal.html)

### 詳細
プロアクティブ・オートヒールは、以下の 2 種類のルールのいずれかに違反した Webアプリケーションのプロセスを動的に監視し、再起動を試みます。

- Percent Memory Rule (% メモリルール)
プロセスのプライベートバイトが 30 秒にわたって制限の 90％ を超えていないかどうかを監視します。Spec により以下のような違いがあります。

| Instance Size | Small (32bit) | Small (64bit) | Medium (32bit) | Medium (64bit) | Large (32bit) | Large (64bit) |
|---------------|---------------|---------------|----------------|----------------|---------------|---------------|
| Memory        | 1.75GB        | 1.75GB        | 3.5GB         | 3.5GB         | 4GB           | 7GB           |


- Percent Request Rule (% リクエストルール)
リクエストの応答時間が一定時間以上かかる場合、かつ、特にそれが大部分のリクエストである場合に、このルールが発火します。具体的には以下です。

  - リクエストの 80% 以上が 200秒 以上かかる
  - 上記の条件が満たされたとき、120 秒のローリングタイムウィンドウ内で最低でも 5 回のリクエストがある (プロセスの warm-up 中はアクティブにならない)

Percent Memory Rule と Percent Request Rule のいずれかのルールが破られた場合、Webアプリのプロセスは再起動します。インスタンスの再起動やWebアプリ全体の再起動ではなく、また、複数のインスタンスが存在する場合、プロセスがルールに違反した特定のインスタンスに対してのみルールが適用され、残りのインスタンスは影響を受けません。上記 blog によると過剰な再起動を防ぐため、再起動が多すぎる場合、両方のルールが 3 時間自動で無効化されるとのことです。

## 終わり
以上、2 種類の Azure App ServiceのAuto-heal機能について解説しました。ぜひ必要に応じて、活用をしてみていただければと思います。

## 参考
- Introducing Proactive Auto Heal (App Service Team Blog)
https://azure.github.io/AppService/2017/08/17/Introducing-Proactive-Auto-Heal.html

- Announcing the New Auto Healing Experience in App Service Diagnostics (App Service Team Blog)
https://azure.github.io/AppService/2018/09/10/Announcing-the-New-Auto-Healing-Experience-in-App-Service-Diagnostics.html