Azure アプリ サービス プラットフォームでメモリ ダンプをキャプチャする
この記事では、メモリ ダンプをキャプチャするための Microsoft Azure アプリ Service のデバッグ機能に関するガイダンスを提供します。 使用するキャプチャ方法は、パフォーマンスまたは可用性の問題をトラブルシューティングするためにメモリ ダンプをキャプチャするシナリオによって決まります。 たとえば、メモリ ダンプのキャプチャは、過剰なメモリ消費が発生しているプロセスと、例外をスローするプロセスや応答速度が遅いプロセスの場合とは異なります。 このコンテキストのプロセスは、w3wp.exeとして実行される インターネット インフォメーション サービス (IIS) ワーカー プロセス (W3WP) です。
Azure アプリ サービスのデバッグ機能へのメモリ ダンプ シナリオのマッピング
次の表は、各 App Service 機能がメモリ ダンプを生成するために実行するコマンドに関する推奨事項を示しています。 メモリ ダンプをキャプチャする方法は非常に多く、プロセスが混乱する可能性があります。 W3WP メモリ ダンプのキャプチャに既に習熟している場合、この情報はアプローチを変更するためのものではありません。 代わりに、まだユーザー設定を開発していない未経験のユーザーにガイダンスを提供したいと考えています。
シナリオ | Azure アプリ サービスのデバッグ機能 | command |
---|---|---|
応答しないか遅い | 自動修復 (要求期間) | procdump -accepteula -r -dc "Message" -ma <PID> <PATH> |
クラッシュ (プロセス終了) | クラッシュの監視 | DbgHost を使用してメモリ ダンプをキャプチャする |
クラッシュ (処理された例外) | Application Insights/Log Analytics のトレース | なし |
クラッシュ (ハンドルされない例外) | Application Insights Snapshot Debugger | なし |
過剰な CPU 使用率 | プロアクティブ CPU 監視 | procdump -accepteula -dc "Message" -ma <PID> <PATH> |
過剰なメモリ消費 | 自動回復 (メモリ制限) | procdump -accepteula -r -dc "Message" -ma <PID> <PATH> |
Note
応答しないシナリオまたは低速シナリオで W3WP プロセス メモリ ダンプをキャプチャするためのセカンダリ推奨事項があります。 そのシナリオが再現可能で、ダンプをすぐにキャプチャする場合は、 メモリ ダンプ 診断ツールを使用できます。 このツールは、Azure portal の特定の App Service Web アプリの Diagnose と解決の問題 ツールセット ページにあります。 一般的な例外とパフォーマンスの低下を確認するもう 1 つの場所は、 アプリケーション イベント ログ ページにあります。 (アプリケーション ログには、からもアクセスできます。問題の診断と解決ページ)。)「拡張 Azure アプリ サービスのデバッグ機能の説明」セクションで、使用可能なすべてのメソッドについて説明します。
拡張されたプロセス シナリオの説明
このセクションでは、前の表に示した 6 つのシナリオについて詳しく説明します。
応答しないシナリオまたは低速なシナリオ
Web サーバーに対して要求が行われる場合は、通常、一部のコードを実行する必要があります。 コードの実行は、スレッドの w3wp.exe プロセス内で実行されます。 各スレッドには、現在実行中の内容を示すスタックがあります。
応答しないシナリオは、永続的な (タイムアウトする可能性がある) か遅い可能性があります。 したがって、応答しないシナリオは、要求の実行に予想以上に時間がかかるシナリオです。 遅いと考えられる内容は、コードの動作によって異なります。 一部のユーザーの場合、3 秒の遅延が遅くなります。 それ以外の場合は、15 秒の遅延が許容されます。 基本的に、パフォーマンス メトリックが低速であることを示す場合、またはスーパー ユーザーがサーバーの応答が通常よりも遅いと述べている場合は、応答しないシナリオまたは低速なシナリオがあります。
クラッシュ (プロセス終了) シナリオ
Microsoft .NET Framework は長年にわたり、例外の処理を改善してきました。 現在のバージョンの .NET では、例外処理エクスペリエンスがさらに向上しています。
これまで、開発者が try-catch ブロック内にコード スニペットを配置せず、例外がスローされた場合、プロセスは終了します。 その場合、開発者のコード内の未処理の例外によってプロセスが終了しました。 より新しいバージョンの .NET では、コードを実行しているプロセスがクラッシュしないように、これらの "ハンドルされない" 例外の一部が処理されます。 ただし、すべてのハンドルされない例外がカスタム コードから直接スローされるわけではありません。 たとえば、アクセス違反 (0xC0000005や0x80070005など) やスタック オーバーフローは、プロセスを終了できます。
クラッシュ (処理された例外) シナリオ
ソフトウェア開発者は、コードが実行される可能性のあるすべてのシナリオを特定するために特別な注意を払いますが、予期しない事態が発生する可能性があります。 次のエラーによって例外がトリガーされる場合があります。
- 予期しない null 値
- 無効なキャスト
- インスタンス化されたオブジェクトが見つからない
コードの実行を try-catch コード ブロックに配置することをお勧めします。 開発者がこれらのブロックを使用する場合、予期しないイベントに続くものを具体的に管理することで、コードは正常に失敗する機会があります。 処理された例外は、try ブロック内でスローされ、対応する catch ブロックでキャッチされる例外です。 この場合、開発者は例外が発生する可能性があることを予測し、コードのそのセクションを囲む適切な try-catch ブロックをコーディングしました。
catch ブロックでは、問題を再現して最終的に解決できるように、十分な情報をログ ソースにキャプチャすると便利です。 例外は、パフォーマンスの観点から見るとコストの高いコード パスです。 そのため、多くの例外が発生するとパフォーマンスに影響します。
クラッシュ (ハンドルされない例外) シナリオ
ハンドルされない例外は、コードが予期しないアクションを実行しようとしたときに発生します。 Crash (プロセス終了)シナリオと同様に、そのコードは try-catch コード ブロック内に含まれません。 この場合、開発者は、コードのそのセクションで例外が発生する可能性があることを予測しませんでした。
このシナリオは、前の 2 つの例外シナリオとは異なります。 Crash (ハンドルされない例外)シナリオでは、問題のコードは開発者が記述したコードです。 例外をスローするのはフレームワーク コードではなく、 w3wp.exe プロセスを強制終了する未処理の例外の 1 つではありません。 また、例外をスローしているコードは try-catch ブロック内にないため、例外を適切に処理する機会はありません。 コードのトラブルシューティングは、最初はもう少し複雑です。 目標は、このハンドルされない例外をスローしているメソッドを識別する例外テキスト、型、スタックを見つけることです。 この情報を使用すると、try-catch コード ブロックを追加する必要がある場所を特定できます。 その後、開発者は同様のロジックを追加して、 Crash (ハンドルされない例外) シナリオに存在する必要がある例外の詳細をログに記録できます。
過剰な CPU 使用率のシナリオ
過剰な CPU 使用率とは この状況は、コードの動作に依存します。 一般に、 w3wp.exe プロセスの CPU 使用率が 80% の場合、アプリケーションはさまざまな症状を引き起こす重大な状況にあります。 考えられる症状は次のとおりです。
- 速度低下
- エラー
- その他の未定義の動作
Web サイトが静的 HTML ファイルを配信しているだけの場合、CPU 使用率が 20% であっても過剰と見なされる可能性があります。 メモリ ダンプを生成して過剰な CPU スパイクの事後トラブルシューティングを行っても、それを使用している特定の方法を特定するのに役立たない可能性があります。 実行できる最善の方法は、最も時間がかかっている可能性が高い要求を特定し、特定された方法をテストして問題を再現することです。 この手順では、そのバーストをキャプチャしたパフォーマンス システムでパフォーマンス モニターを実行しないことを前提としています。 多くの場合、モニターを常にリアルタイムで実行することで、パフォーマンスの問題が発生する可能性があります。
過剰なメモリ消費のシナリオ
アプリケーションが 32 ビット プロセスで実行されている場合、過剰なメモリ消費が問題になる可能性があります。 アクティビティの量が少なくても、割り当てられた仮想アドレス空間が 2 ~ 3 GB 消費される可能性があります。 32 ビット プロセスは、使用可能な物理メモリの量に関係なく、合計 4 GB を超えてはいけません。
64 ビット プロセスには、32 ビット プロセスよりも多くのメモリが割り当てられます。 64 ビット プロセスは、割り当てられた仮想アドレス空間を使用するよりも、サーバー上の物理メモリの量を消費する可能性が高くなります。
そのため、過剰なメモリ消費の問題を構成するものは、次の要因によって異なります。
- プロセスのビット数 (32 ビットまたは 64 ビット)
- "通常" と見なされるメモリ使用量。
プロセスで予想よりも多くのメモリを消費している場合は、分析用のメモリ ダンプを収集して、メモリ リソースを消費しているものを特定します。 詳細については、「 メモリの消費が多すぎる場合に App Service のメモリ ダンプを作成するを参照してください。
メモリ ダンプがトラブルシューティングに役立つさまざまなプロセス シナリオについてもう少し詳しく説明したので、Azure アプリ サービス プラットフォームでメモリ ダンプをキャプチャするための推奨されるツールについて説明します。
拡張されたAzure アプリ サービスのデバッグ機能の説明
「Azure アプリ サービス デバッグ機能へのメモリ ダンプ シナリオのマッピング」セクションの表で、メモリ ダンプの収集を対象とする 6 つのデバッグ機能を特定しました。 これらの各機能は、 Azure ポータル内からアクセスできます Diagnose と問題の解決 ページで Diagnostic Tools タイルを選択するとします。
以降のセクションでは、これらの各デバッグ機能について詳しく説明します。
自動修復 (要求期間) 機能
自動修復 (要求期間) 機能は、応答の完了に予想以上に時間がかかっている場合にメモリ ダンプをキャプチャするのに役立ちます。 前のスクリーンショットの Diagnostic Tools タイルに、Auto-Heal へのリンクが表示されます。 そのリンクを選択して機能に直接移動するか、 Diagnostic Tools タイルを選択して、 Diagnostic Tools ページで使用可能なすべてのツールを確認します。 この機能を構成する方法については、次の記事を参照してください。
自動回復機能は、次のスクリーンショットに示されています。
"メモリ ダンプの収集" という名前のもう 1 つの機能は、問題が現在発生しているか再現可能である場合に、このシナリオで役立ちます。 この機能により、手動で必要に応じてメモリ ダンプが迅速に収集されます。
メモリ ダンプ機能を収集する
メモリ ダンプの収集機能の構成については、「 Collect memory dump app servicesを参照してください。 この方法では、手動による介入が必要です。 次のスクリーンショットは、 [メモリ ダンプの収集 ] ページを示しています。
この機能を使用するには、メモリ ダンプを格納するストレージ アカウントを選択します。 次に、メモリ ダンプを収集するサーバー インスタンスを選択します。 複数のインスタンスがある場合は、そのインスタンスでデバッグ中の問題が発生していることを確認してください。 運用環境のアプリケーションで再起動が最適でない可能性があることに注意してください。
クラッシュ監視機能
クラッシュ監視機能は、ハンドルされない例外によって W3WP プロセスが終了する場合に、メモリ ダンプをキャプチャするのに役立ちます。 次のスクリーンショットは、Diagnostic Tools の Crash Monitoring ページを示しています。
Azure アプリ Service でクラッシュ監視機能を構成する方法に関するガイド付きチュートリアルについては、Azure アプリ Service での Crash 監視を参照してください。
Application Insights/Log Analytics 機能のトレース
処理された例外は、try-catch ブロック内に含まれるコードが、予期しない、またはサポートされていないアクションを実行しようとするシナリオです。 たとえば、次のコード スニペットは、これが無効な操作であっても、数値を 0 で除算しようとします。
decimal percentage = 0, number = 1000, total = 0;
try
{
percentage = number / total;
}
catch (DivideByZeroException divEx)
{
_logger.LogError("A handled exception just happened: -> {divEx.Message}", divEx.Message);
}
このコード スニペットでは、サポートされていない数学演算が try-catch ブロック内に配置されるため、処理される 0 除算例外が発生します。 Application Insights では、アプリケーション コードに Microsoft.ApplicationInsights NuGet パッケージを意図的に含め、情報をログに記録するコードを追加しない限り、処理された例外はログに記録されません。 コードの追加後に例外が発生した場合は、次のスクリーンショットに示すように、Log Analytics でエントリを表示できます。
次の Kusto コードには、Log Analytics からデータを抽出するために使用されるクエリが含まれています。
traces
| where message has "handled"
| project timestamp, severityLevel, message, operation_Name, cloud_RoleInstance
message
列は、例外の根本原因を見つけるために必要な詳細を格納できる場所です。 このクエリの記述に使用されるコードは、0 除算コード スニペットにあります。 このコードを記述したソフトウェア開発者は、この種の例外と根本原因を分析するためにキャプチャするために必要な属性について尋ねるのに最適な人物です。
この機能をアプリケーション コードに追加する最適な方法は、アプリケーション コード スタックと、使用しているバージョン (ASP.NET、ASP.NET Core、MVC、Razor など) によって異なります。 シナリオに最適なアプローチを決定するには、.NET を使用Application Insights のログ記録を確認します。
アプリケーション イベント ログ (処理された例外) 機能
ハンドルされない例外は、次のスクリーンショットに示すように、Azure portal の Diagnostic Tools の Application イベント ログ ページで処理された例外を見つけることができます。
この状況では、コードを通じてログに記録したのと同じエラー メッセージが表示されます。 ただし、Application Insights トレース ログのクエリをカスタマイズする方法に関する柔軟性が失われます。
Application Insights スナップショット デバッガー機能
ハンドルされない例外は、次のセクションの出力テキストに示すように、 アプリケーション イベント ログ ページにも記録されます。 ただし、Application Insights スナップショット デバッガーを 可能にすることもできます。 この方法では、アプリケーションにコードを追加する必要はありません。
アプリケーション イベント ログ (ハンドルされない例外) 機能
次の出力は、Azure portal の Diagnostic Tools の Application イベント ログ ページから出力されます。 ハンドルされないアプリケーション例外のテキストの例を示します。
Category: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware
EventId: 1
SpanId: 311d8cb5d10b1a6e
TraceId: 041929768411c12f1c3f1ccbc91f6751
ParentId: 0000000000000000
RequestId: 8000006d-0001-bf00-b63f-84710c7967bb
RequestPath: /Unhandled
An unhandled exception has occurred while executing the request.
Exception:
System.DivideByZeroException: Attempted to divide by zero.
at System.Decimal.DecCalc.VarDecDiv(DecCalc& d1, DecCalc& d2)
at System.Decimal.op_Division(Decimal d1, Decimal d2)
at contosotest.Pages.Pages Unhandled.ExecuteAsync()
in C:\Users\contoso\source\repos\contosorepo\contosorepo\Pages\Unhandled.cshtml:line 12
アプリケーション ログの処理された例外との違いの 1 つは、メソッドを識別するスタックと、例外がスローされる行の存在です。 また、 Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware 機能には、この未処理の例外をキャッチしてプロセスの終了を回避するコードが含まれていると想定しても問題ありません。 例外は、次のスクリーンショットに示すように、Failures ページの Exceptions タブの Application Insights に表示されます。
このビューには、 Exceptionsが検索対象のビューだけでなく、すべて表示されます。 アプリケーションで発生するすべての例外のグラフィカル表現は、システムの正常性の概要を把握するのに役立ちます。 Application Insights ダッシュボードは、アプリケーション イベント ログと比較して視覚的に役立ちます。
プロアクティブ CPU 監視機能
過剰な CPU 使用率のシナリオでは、プロアクティブ CPU 監視ツールを使用できます。 このツールの詳細については、「 発生する前に CPU の問題を解決するを参照してください。 次の図は、Diagnostic Tools の Proactive CPU Monitoring ページを示しています。
80% 以上の CPU 使用率は、即時調査が必要な重大な状況と考える必要があります。 Proactive CPU Monitoring ページでは、次のデータ監視カテゴリに基づいてメモリ ダンプをキャプチャするシナリオを設定できます。
- CPU しきい値
- しきい値 (秒)
- モニターの頻度
CPU しきい値 は、対象となるプロセスで使用されるコンピューター CPU の量 (この場合は W3WP) を識別します。 しきい値 (秒 は、CPU が CPU しきい値で使用された時間です。 たとえば、合計 30 秒間の CPU 使用率が 75% の場合、メモリ ダンプがキャプチャされます。 [CPU 監視ページで構成されているように、プロセスは 15 秒ごとにしきい値違反をチェックします。
自動回復 (メモリ制限) 機能
自動修復 (メモリ制限) 機能は、プロセスが予想よりも多くのメモリを消費している場合にメモリ ダンプをキャプチャする場合に便利です。 ここでも、ビット数 (32 または 64) に注意してください。 32 ビット プロセス コンテキストでメモリ不足が発生し、メモリ消費量が予想される場合は、ビット数を 64 に変更することを検討してください。 通常、ビット数を変更する場合は、アプリケーションも再コンパイルする必要があります。
ビット数を変更しても、使用されるメモリの量は減りません。 これにより、プロセスは 4 GB を超える合計メモリを使用できます。 ただし、メモリの消費量が想定どおりでない場合は、この機能を使用して、メモリを消費しているものを特定できます。 その後、メモリ使用量を制御するアクションを実行できます。
"Expanded Azure アプリ Service のデバッグ機能の説明" セクションでは、最初のスクリーンショットの Diagnostic Tools タイルで Auto-Heal へのリンクを確認できます。 そのリンクを選択して機能に直接移動するか、タイルを選択して Diagnostic Tools ページで使用可能なすべてのツールを確認します。 詳細については、「Azure アプリ サービス診断の概要」の「自動復旧」セクションを参照してください。
自動回復機能は、次のスクリーンショットに示されています。
メモリ制限 タイルを選択すると、メモリ制限に違反したときにメモリ ダンプのキャプチャをトリガーするメモリ値を入力できます。 たとえば、値として「 6291456 」と入力すると、6 GB のメモリが消費されたときに W3WP プロセスのメモリ ダンプが取得されます。
メモリ ダンプの収集機能は、問題が現在発生しているか再現可能な場合に、このシナリオで役立ちます。 この機能により、手動で必要に応じてメモリ ダンプが迅速に収集されます。 詳細については、「 メモリ ダンプの収集」 セクションを参照してください。
展開されたコマンドの説明
メモリ ダンプコレクションの技術は、研究、経験、完璧に時間がかかります。 既に説明したように、「展開されたプロセス シナリオの説明」セクションの表に示すように、プロセスに表示される症状に基づいて、さまざまな手順 が行。 これに対し、次の表では、Azure アプリ サービスのメモリ ダンプ キャプチャ コマンドと、Kudu コンソールから手動で実行する procdump コマンドを比較します。
シナリオ | Azure アプリ Service コマンド | 一般的な procdump コマンド |
---|---|---|
応答しないか遅い | procdump -accepteula -r -dc "Message" -ma <PID> <PATH> |
procdump -accepteula -ma -n 3 -s # <PID> |
クラッシュ (プロセス終了) | DbgHost を使用してメモリ ダンプをキャプチャする | procdump -accepteula -ma -t <PID> |
クラッシュ (処理された例外) | なし (Application Insights) | procdump -accepteula -ma -e 1 -f <filter> <PID> |
クラッシュ (ハンドルされない例外) | なし (Application Insights スナップショット デバッガー) | procdump -accepteula -ma -e <PID> |
過剰な CPU 使用率 | procdump -accepteula -dc "Message" -ma <PID> <PATH> |
procdump -accepteula -ma -n 3 -s # -c 80 <PID> |
過剰なメモリ消費 | procdump -accepteula -r -dc "Message" -ma <PID> <PATH> |
procdump -accepteula -ma -m 2000 <PID> |
Azure アプリ サービスのメモリ ダンプ キャプチャ機能で使用するコマンドは、ダンプを手動でキャプチャした場合に使用する procdump コマンドとは異なります。 前のセクションを確認すると、Azure アプリ サービスのメモリ ダンプ 収集ポータル機能によって構成が公開されていることがわかります。 たとえば、テーブルの過剰なメモリ消費シナリオでは、プラットフォームが実行するコマンドにメモリしきい値が含まれません。 ただし、一般的な procdump コマンド列に示されているコマンドでは、メモリのしきい値が指定されます。
DaaS (サービスとしての診断) という名前のツールは、Azure アプリ サービス デバッグ ポータルで指定された構成の管理と監視を担当します。 このツールは、Web アプリを実行する仮想マシン (VM) 上で Web ジョブとして実行されます。 このツールの利点は、Web ファーム内の特定の VM をターゲットにできることです。 procdump を直接使用してメモリ ダンプをキャプチャしようとすると、特定のインスタンスでそのコマンドを識別、ターゲット化、アクセス、実行することが困難な場合があります。 DaaS の詳細については、「 DaaS - Azure Web サイトのサービスとしての診断」を参照してください。
過剰な CPU 使用率 は、推奨される procdump パターンに一致するように、プラットフォームがメモリ ダンプコレクションを管理するもう 1 つの理由です。 前の表に示すように、procdump コマンドは、CPU 使用率が 80% (-c 80
) 以上の場合に、30 秒離れた 3 つの (-n 3
) 完全メモリ ダンプ (-ma
) を収集します (-s #
、#
は 30)。 最後に、procdump -accepteula -ma -n 3 -s # -c 80 <PID>
コマンドにプロセス ID (<PID>
) を指定します。
ポータルの構成は、 "プロアクティブ CPU 監視" セクションで確認できます。 簡潔にするために、このセクションでは、最初の 3 つの構成オプション ( CPU しきい値 (-c
)、 Threshold Seconds (-s
)、 Monitor Frequency のみを示しました。 次のスクリーンショットは、 Configure Action、 Maximum Actions (-n
)、 Maximum Duration が追加で使用可能な機能であることを示しています。
メモリ ダンプをキャプチャするためのさまざまな方法を検討した後、次の手順はキャプチャの作成を練習することです。 GitHub のコード例を、 IIS デバッグ ラボ および Azure Functions と組み合わせて使用して、2 つの表に記載されている各シナリオをシミュレートできます。 コードを Azure アプリ Service プラットフォームにデプロイした後、これらのツールを使用して、特定の各シナリオのメモリ ダンプをキャプチャできます。 時間の経過と練習後に、Azure アプリ サービスのデバッグ機能を使用してメモリ ダンプをキャプチャするためのアプローチを完成させることができます。 次の一覧には、メモリ ダンプの収集について学習し続ける際に考慮すべきいくつかの推奨事項が含まれています。
メモリ ダンプをキャプチャすると、大量のシステム リソースが消費され、パフォーマンスがさらに中断されます。
最初の機会にメモリ ダンプをキャプチャすることは、キャプチャが多すぎる可能性があるため、最適ではありません。 これらの初回のメモリ ダンプは、おそらく無関係です。
W3WP メモリ ダンプをキャプチャする前に、Application Insights を無効にすることをお勧めします。
メモリ ダンプが収集された後、次の手順は、メモリ ダンプを分析して問題の原因を特定し、その問題を修正することです。
次の手順 (メモリ ダンプの分析)
メモリ ダンプの分析方法については、この記事の範囲外です。 ただし、 Defrag Tools トレーニング シリーズや、知っておくべき WinDbg コマンドの リストなど、その対象には多くのリソース。
前のスクリーンショットの Configure Action オプションに気付いたかもしれません。 このオプションの既定の設定は CollectAndKill です。 この設定は、メモリ ダンプが収集された後にプロセスが強制終了されることを意味します。 CollectKillAndAnalyze という名前の設定は、収集されたメモリ ダンプを分析します。 そのシナリオでは、プラットフォーム分析で問題が見つかる可能性があるため、WinDbg でメモリ ダンプを開いて分析する必要はありません。
Azure アプリ サービス プラットフォームでのパフォーマンスの問題のトラブルシューティングと診断には、他にもオプションがあります。 この記事では、メモリ ダンプの収集に焦点を当て、これらのメソッドを使用して診断に近づくためのいくつかの推奨事項を示します。 既にコレクションプロシージャを学習し、経験し、完成させ、それらがうまく機能する場合は、これらの手順を引き続き使用する必要があります。
お問い合わせはこちらから
質問がある場合やヘルプが必要な場合は、サポート要求を作成するか、Azure コミュニティ サポートにお問い合わせください。 Azure フィードバック コミュニティに製品フィードバックを送信することもできます。