Azure App Service プラットフォームでメモリ ダンプをキャプチャする
この記事では、メモリ ダンプをキャプチャするための Microsoft Azure App Service デバッグ機能に関するガイダンスを提供します。 使用するキャプチャ方法は、パフォーマンスまたは可用性の問題のトラブルシューティングのためにメモリ ダンプをキャプチャするシナリオによって決まります。 たとえば、メモリ ダンプのキャプチャは、メモリ消費量が多すぎるプロセスの場合と、例外をスローするプロセスや応答速度が遅いプロセスの場合とは異なります。 このコンテキストのプロセスは、インターネット インフォメーション サービス (IIS) ワーカー プロセス ( w3wp.exeとして実行 される W3WP) です。
Azure App Service デバッグ機能へのメモリ ダンプ シナリオのマッピング
次の表は、各 App Service 機能がメモリ ダンプを生成するために実行するコマンドに関する推奨事項を示しています。 メモリ ダンプをキャプチャする方法は非常に多く、プロセスが混乱する可能性があります。 W3WP メモリ ダンプのキャプチャに既に習熟している場合、この情報はアプローチを変更するためのものではありません。 代わりに、まだ設定を開発していない経験の浅いユーザーにガイダンスを提供したいと考えています。
シナリオ | Azure App Service のデバッグ機能 | command |
---|---|---|
応答しないか遅い | 自動修復 (要求期間) | procdump -accepteula -r -dc "Message" -ma <PID> <PATH> |
クラッシュ (プロセス終了) | クラッシュ監視 | DbgHost を使用してメモリ ダンプをキャプチャする |
クラッシュ (処理された例外) | Application Insights/Log Analytics のトレース | なし |
クラッシュ (未処理の例外) | Application Insights スナップショット デバッガー | なし |
CPU 使用率が高すぎる | プロアクティブ CPU 監視 | procdump -accepteula -dc "Message" -ma <PID> <PATH> |
メモリ消費量が多すぎる | 自動修復 (メモリ制限) | procdump -accepteula -r -dc "Message" -ma <PID> <PATH> |
注:
応答しないシナリオまたは低速なシナリオで W3WP プロセス メモリ ダンプをキャプチャするためのセカンダリレコメンデーションがあります。 そのシナリオが再現可能であり、ダンプをすぐにキャプチャする場合は、 メモリ ダンプの収集 診断ツールを使用できます。 このツールは、Azure portal の特定の App Service Web アプリの [問題の診断と解決 ] ツールセット ページにあります。 一般的な例外とパフォーマンスの低下を確認する別の場所は、[ アプリケーション イベント ログ] ページにあります。 ([ 問題の診断と解決 ] ページからもアプリケーション ログにアクセスできます)。 「拡張された Azure App Service デバッグ機能の説明」 セクションで、使用可能なすべての方法について説明します。
拡張されたプロセス シナリオの説明
このセクションでは、前の表に示した 6 つのシナリオについて詳しく説明します。
応答しないシナリオまたは低速シナリオ
Web サーバーに対して要求が行われると、通常、一部のコードを実行する必要があります。 コードの実行は、スレッドの w3wp.exe プロセス内で実行されます。 各スレッドには、現在実行中の内容を示すスタックがあります。
応答しないシナリオは、永続的 (タイムアウトになる可能性があります) または低速のいずれかです。 したがって、応答しないシナリオは、要求の実行に予想以上に時間がかかるシナリオです。 遅いと考えられる点は、コードの実行内容によって異なります。 一部のユーザーの場合、3 秒の遅延が遅くなります。 その他の場合は、15 秒の遅延が許容されます。 基本的に、速度の低下を示すパフォーマンス メトリックが表示される場合、またはスーパー ユーザーがサーバーの応答が通常よりも遅いと述べている場合は、応答しないシナリオや低速なシナリオがあります。
クラッシュ (プロセス終了) シナリオ
長年にわたって、Microsoft .NET Framework は例外の処理を改善してきました。 現在のバージョンの .NET では、例外処理エクスペリエンスがさらに向上しています。
これまで、開発者が try-catch ブロック内にコード スニペットを配置せず、例外がスローされた場合、プロセスは終了しました。 その場合、開発者のコードの未処理の例外によってプロセスが終了しました。 より新しいバージョンの .NET では、コードを実行しているプロセスがクラッシュしないように、これらの "未処理" 例外の一部が処理されます。 ただし、すべての未処理の例外がカスタム コードから直接スローされるわけではありません。 たとえば、アクセス違反 (0xC0000005や0x80070005など) やスタック オーバーフローによってプロセスが終了する可能性があります。
クラッシュ (処理された例外) シナリオ
ソフトウェア開発者は、コードが実行される可能性のあるすべてのシナリオを特定するために特別な注意を払いますが、予期しない問題が発生する可能性があります。 次のエラーによって例外がトリガーされる可能性があります。
- 予期しない null 値
- 無効なキャスト
- インスタンス化されたオブジェクトが見つからない
コードの実行を try-catch コード ブロックに入れるのがベスト プラクティスです。 開発者がこれらのブロックを使用する場合、予期しないイベントに続くものを具体的に管理することで、コードは正常に失敗する機会があります。 処理された例外は、try ブロック内でスローされ、対応する catch ブロックでキャッチされる例外です。 この場合、開発者は例外が発生し、コードのそのセクションを囲む適切な try-catch ブロックをコーディングする可能性があると予想しました。
catch ブロックでは、問題を再現して最終的に解決できるように、十分な情報をログ ソースにキャプチャすると便利です。 例外は、パフォーマンスの観点からコストの高いコード パスです。 そのため、多くの例外が発生するとパフォーマンスに影響します。
クラッシュ (未処理の例外) シナリオ
未処理の例外は、コードが予期しないアクションを実行しようとしたときに発生します。 クラッシュ (プロセス終了) シナリオと同様に、そのコードは try-catch コード ブロックに含まれません。 この場合、開発者は、コードのそのセクションで例外が発生する可能性があるとは予測していませんでした。
このシナリオは、前の 2 つの例外シナリオとは異なります。 クラッシュ (未処理の例外) シナリオでは、問題のコードは開発者が記述したコードです。 例外をスローするのはフレームワーク コードではなく、 w3wp.exe プロセスを強制終了する未処理の例外の 1 つではありません。 また、例外をスローするコードは try-catch ブロック内にないため、例外を適切に処理する機会はありません。 コードのトラブルシューティングは、最初はもう少し複雑です。 目標は、この未処理の例外をスローしているメソッドを識別する例外テキスト、型、スタックを見つけることです。 この情報を使用すると、try-catch コード ブロックを追加する必要がある場所を特定できます。 次に、開発者は同様のロジックを追加して、 クラッシュ (未処理の例外) シナリオに存在する必要がある例外の詳細をログに記録できます。
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 App Service プラットフォームでメモリ ダンプをキャプチャするための推奨ツールについて説明します。
拡張された Azure App Service デバッグ機能の説明
「メモリ ダンプ シナリオを Azure App Service デバッグ機能にマッピングする」セクションの表で、メモリ ダンプの収集を対象とする 6 つのデバッグ機能を特定しました。 これらの各機能には、[診断ツール] タイルを選択すると、[問題の診断と解決] ページの Azure portal 内からアクセスできます。
以降のセクションでは、これらの各デバッグ機能について詳しく説明します。
自動修復 (要求期間) 機能
自動修復 (要求期間) 機能は、応答の完了に予想以上に時間がかかる場合にメモリ ダンプをキャプチャするのに役立ちます。 前のスクリーンショットの [診断ツール] タイルに[自動修復] へのリンクが表示されます。 そのリンクを選択して機能に直接移動するか、[ 診断ツール ] タイルを選択して、[ 診断ツール] ページで使用可能なすべてのツールを確認します。 この機能を構成する方法については、次の記事を参照してください。
自動修復機能は、次のスクリーンショットに示されています。
"メモリ ダンプの収集" という名前のもう 1 つの機能は、問題が現在発生している場合や再現可能な場合に、このシナリオで役立ちます。 この機能を使用すると、手動で必要に応じてメモリ ダンプをすばやく収集できます。
メモリ ダンプ機能を収集する
メモリ ダンプの収集機能の構成については、「メモリ ダンプ アプリ サービスの収集」を参照してください。 この方法では、手動による介入が必要です。 次のスクリーンショットは、[ メモリ ダンプの収集] ページを 示しています。
この機能を使用するには、メモリ ダンプを格納するストレージ アカウントを選択します。 次に、メモリ ダンプを収集するサーバー インスタンスを選択します。 インスタンスが 1 つ以上ある場合は、そのインスタンスでデバッグ中の問題が発生していることを確認します。 運用中の運用アプリケーションでは、再起動が最適でない可能性があることに注意してください。
クラッシュ監視機能
クラッシュ監視機能は、未処理の例外によって W3WP プロセスが終了する場合に、メモリ ダンプをキャプチャするのに役立ちます。 次のスクリーンショットは、診断ツールの [クラッシュ監視] ページを示しています。
Azure App Service でクラッシュ監視機能を構成する方法に関するガイド付きチュートリアルについては、「Azure App Service でのクラッシュ監視」を参照してください。
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 の診断ツールの [アプリケーション イベント ログ] ページで確認できます。
この状況では、コードを通じてログに記録したのと同じエラー メッセージが表示されます。 ただし、Application Insights トレース ログに対するクエリをカスタマイズする方法の柔軟性が失われます。
Application Insights スナップショット デバッガー機能
未処理の例外は、次のセクションの出力テキストに示すように、[ アプリケーション イベント ログ] ページにも記録されます。 ただし、 Application Insights スナップショット デバッガーを有効にすることもできます。 この方法では、アプリケーションにコードを追加する必要はありません。
アプリケーション イベント ログ (未処理の例外) 機能
次の出力は、Azure portal の診断ツールの [アプリケーション イベント ログ] ページから出力されます。 ハンドルされないアプリケーション例外のテキストの例を示します。
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 機能には、この未処理の例外をキャッチしてプロセスの終了を回避するためのコードが含まれていると安全に想定できます。 次のスクリーンショットに示すように、[エラー] ページの [例外] タブの Application Insights に例外が表示されます。
このビューには、検索対象の 例外だけでなく、すべての例外が表示されます。 アプリケーションで発生するすべての例外のグラフィカル表現は、システムの正常性の概要を把握するのに役立ちます。 Application Insights ダッシュボードは、Application イベント ログと比較して視覚的に役立ちます。
プロアクティブ CPU 監視機能
CPU 使用率の過剰なシナリオでは、プロアクティブ CPU 監視ツールを使用できます。 このツールの詳細については、「 CPU の問題が発生する前に CPU の問題を軽減する」を参照してください。 次の図は、診断ツールの [プロアクティブ CPU 監視] ページを示しています。
80% 以上の CPU 使用率は、即時調査が必要な重大な状況と考える必要があります。 [ プロアクティブ CPU 監視] ページでは、次のデータ監視カテゴリに基づいて、メモリ ダンプをキャプチャするシナリオを設定できます。
- CPU しきい値
- しきい値 (秒)
- モニターの頻度
CPU しきい値 は、対象となるプロセスで使用されるコンピューター CPU の量 (この場合は W3WP) を識別します。 しきい値秒 は、CPU しきい 値で CPU が使用された時間です。 たとえば、合計 30 秒間に 75% の CPU 使用率がある場合、メモリ ダンプがキャプチャされます。 [プロアクティブ CPU 監視] ページで構成されている場合、プロセスは 15 秒ごとにしきい値違反がないかチェックされます。
自動修復 (メモリ制限) 機能
自動修復 (メモリ制限) 機能は、プロセスが予想よりも多くのメモリを消費している場合にメモリ ダンプをキャプチャするのに役立ちます。 繰り返しになりますが、ビット数 (32 または 64) に注意してください。 32 ビット プロセス コンテキストでメモリ不足が発生し、メモリ消費量が予想される場合は、ビット数を 64 に変更することを検討してください。 通常、ビット数を変更する場合は、アプリケーションも再コンパイルする必要があります。
ビット数を変更しても、使用されるメモリの量は減りません。 これにより、プロセスで 4 GB を超える合計メモリを使用できます。 ただし、メモリ消費量が想定どおりに行われていない場合は、この機能を使用してメモリを消費している内容を特定できます。 その後、メモリ消費量を制御するアクションを実行できます。
[展開された Azure App Service デバッグ機能の説明] セクションでは、最初のスクリーンショットの [診断ツール] タイルに自動修復へのリンクが表示されます。 そのリンクを選択して機能に直接移動するか、タイルを選択し、[ 診断ツール] ページで使用可能なすべてのツールを確認します。 詳細については、「Azure App Service 診断の概要」の「自動修復」セクションを参照してください。
自動修復機能は、次のスクリーンショットに示されています。
[ メモリ制限 ] タイルを選択すると、メモリ制限に違反したときにメモリ ダンプのキャプチャをトリガーするメモリ値を入力できます。 たとえば、 値として「6291456 」と入力すると、6 GB のメモリが消費されたときに W3WP プロセスのメモリ ダンプが取得されます。
メモリ ダンプの収集機能は、問題が現在発生している場合や再現可能な場合に、このシナリオで役立ちます。 この機能を使用すると、手動で必要に応じてメモリ ダンプをすばやく収集できます。 詳細については、「 メモリ ダンプの収集」セクションを 参照してください。
展開されたコマンドの説明
メモリ ダンプコレクションの技術は、学習、経験、完璧に時間がかかります。 学習したように、「 展開されたプロセス シナリオの説明」 セクションの表に示すように、プロセスに表示される症状に基づいて、さまざまな手順が行われます。 一方、次の表では、Azure App Service のメモリ ダンプ キャプチャ コマンドと、Kudu コンソールから手動で実行する procdump コマンドを比較しています。
シナリオ | Azure App 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 App Service のメモリ ダンプキャプチャ機能で使用するコマンドは、ダンプを手動でキャプチャした場合に使用する procdump コマンドとは異なります。 前のセクションを確認すると、Azure App Service のメモリ ダンプ収集ポータル機能によって構成が公開されていることがわかります。 たとえば、テーブル内の過剰なメモリ消費シナリオでは、プラットフォームが実行するコマンドにメモリしきい値が含まれません。 ただし、一般的な procdump コマンド列に示されているコマンドは、メモリしきい値を指定します。
DaaS (サービスとしての診断) という名前のツールは、Azure App Service デバッグ ポータルで指定されている構成の管理と監視を担当します。 このツールは、Web アプリを実行する仮想マシン (VM) で Web ジョブとして実行されます。 このツールの利点は、Web ファーム内の特定の VM をターゲットにできることです。 procdump を直接使用してメモリ ダンプをキャプチャしようとすると、特定のインスタンスでそのコマンドを識別、ターゲット、アクセス、実行することが困難になる可能性があります。 DaaS の詳細については、「 DaaS – Azure Web サイトのサービスとしての診断」を参照してください。
CPU 使用量が多すぎる ことが、推奨される procdump パターンに一致するようにプラットフォームがメモリ ダンプコレクションを管理するもう 1 つの理由です。 前の表に示すように、procdump コマンドは、CPU 使用率が 80% (-ma
) 以上の場合に、30 秒離れた-s #
#
3 つの (-n 3
つまり 30) 完全メモリ ダンプを-c 80
収集します。 最後に、 コマンドにプロセス ID (<PID>
) を指定します。 procdump -accepteula -ma -n 3 -s # -c 80 <PID>
ポータルの構成は 、"プロアクティブ CPU 監視" セクションで確認できます。 簡潔にするために、このセクションでは、最初の 3 つの構成オプション (CPU しきい値 ()、しきい値秒 (-s
-c
)、およびモニター周波数のみが表示されました。 次のスクリーンショットは、 アクションの構成、 最大アクション (-n
)、 最大実行時間 が追加で利用可能な機能であることを示しています。
メモリ ダンプをキャプチャするためのさまざまな方法を検討した後、次の手順はキャプチャの作成を練習することです。 GitHub のコード例を IIS デバッグ ラボ と Azure Functions と組み合わせて使用して、2 つのテーブルに一覧表示されている各シナリオをシミュレートできます。 Azure App Service プラットフォームにコードをデプロイした後、これらのツールを使用して、特定の各シナリオのメモリ ダンプをキャプチャできます。 時間の経過と練習後に、Azure App Service デバッグ機能を使用してメモリ ダンプをキャプチャするためのアプローチを完成させることができます。 次の一覧には、メモリ ダンプの収集について学習を続ける際に考慮すべきいくつかの提案が含まれています。
メモリ ダンプをキャプチャすると、大量のシステム リソースが消費され、パフォーマンスがさらに低下します。
最初の機会にメモリ ダンプをキャプチャすることは最適ではありません。キャプチャが多すぎる可能性があるためです。 これらの初回のメモリ ダンプは、最も可能性の高い無関係です。
W3WP メモリ ダンプをキャプチャする前に、Application Insights を無効にすることをお勧めします。
メモリ ダンプが収集された後、次の手順では、メモリ ダンプを分析して問題の原因を特定し、その問題を修正します。
次の手順 (メモリ ダンプの分析)
メモリ ダンプを分析する方法については、この記事の範囲外です。 ただし、 Defrag Tools トレーニング シリーズや 必須の WinDbg コマンドの一覧など、その対象には多くのリソースがあります。
前のスクリーンショットの [アクションの構成] オプションが表示されている可能性があります。 このオプションの既定の設定は CollectAndKill です。 この設定は、メモリ ダンプが収集された後にプロセスが強制終了されることを意味します。 CollectKillAndAnalyze という名前の設定は、収集されたメモリ ダンプを分析します。 そのシナリオでは、WinDbg でメモリ ダンプを開いて分析する必要がないように、プラットフォーム分析で問題が見つかる可能性があります。
Azure App Service プラットフォームでのパフォーマンスの問題のトラブルシューティングと診断には、他にもオプションがあります。 この記事では、メモリ ダンプ収集に焦点を当て、これらの方法を使用して診断にアプローチするための推奨事項をいくつか示します。 既に収集手順を学習し、経験し、完成させ、それらが適切に機能する場合は、これらの手順を引き続き使用する必要があります。
お問い合わせはこちらから
質問がある場合やヘルプが必要な場合は、サポート要求を作成するか、Azure コミュニティ サポートにお問い合わせください。 Azure フィードバック コミュニティに製品フィードバックを送信することもできます。