ASP.NET アプリケーションから Web サービスを呼び出すときのパフォーマンスの問題

この記事では、Microsoft ASP.NET アプリケーションから Web サービスを呼び出すときに発生するパフォーマンスの問題を解決するためのヘルプを提供します。

元の製品バージョン: ASP.NET
元の KB 番号: 821268

現象

ASP.NET アプリケーションから Web サービスを呼び出すと、競合、パフォーマンスの低下、デッドロックが発生する可能性があります。 クライアントは、要求が応答を停止したり、実行に時間がかかることを報告する場合があります。 デッドロックが疑われる場合は、ワーカー プロセスがリサイクルされる可能性があります。

メソッドを呼び出すと、次の例外エラー メッセージが HttpWebRequest.GetResponse 表示されることがあります。

"System.InvalidOperationException: ThreadPool オブジェクトに、操作を完了するのに十分な空きスレッドができませんでした。

ブラウザーで次の例外エラー メッセージが表示される場合もあります。

"HttpException (0x80004005): 要求がタイムアウトしました。

注:

この記事は、要求を直接行う HttpWebRequest アプリケーションにも適用されます。

原因

この問題は、ASP.NET 呼び出しで要求を実行するために使用できるワーカー スレッドと完了ポート スレッドの数が制限されるために発生する可能性があります。

通常、Web サービスへの呼び出しでは、1 つのワーカー スレッドを使用して、要求を送信するコードを実行し、1 つの完了ポート スレッドが Web サービスからコールバックを受信します。 ただし、要求がリダイレクトされるか、認証が必要な場合、呼び出しでは最大 2 つのワーカー スレッドと 2 つの完了ポート スレッドを使用できます。 そのため、複数の Web サービス呼び出しが同時に発生したときにマネージド ThreadPool を使い果たすことができます。

たとえば、 が 10 個のワーカー スレッドに制限されており、コールバックの実行を待機している 10 個のワーカー スレッドすべてが現在コードを実行しているとします ThreadPool 。 にキューに入 ThreadPool れられた作業項目は、スレッドが使用可能になるまでブロックされるため、コールバックを実行することはできません。

競合の原因として考えられるもう 1 つは、 maxconnection 名前空間が接続の数を System.Net 制限するために使用するパラメーターです。 一般に、この制限は想定どおりに機能します。 ただし、多くのアプリケーションが同時に 1 つの IP アドレスに対して多数の要求を行おうとする場合、スレッドは使用可能な接続を待機する必要があります。

解決方法

これらの問題を解決するには、 Machine.config ファイル内の次のパラメーターを状況に最適に調整できます。

  • maxWorkerThreads
  • minWorkerThreads
  • maxIoThreads
  • minFreeThreads
  • minLocalRequestFreeThreads
  • maxconnection
  • executionTimeout

これらの問題を正常に解決するには、次のアクションを実行します。

  • 同時に実行できる ASP.NET 要求の数を CPU あたり約 12 に制限します。
  • Web サービス コールバックが 内のスレッドを自由に使用することを許可します ThreadPool
  • パラメーターに適切な値を maxconnections 選択します。 使用される IP アドレスと AppDomains の数に基づいて選択します。

注:

ASP.NET 要求の数を CPU あたり 12 個に制限することをお勧めします。 ただし、この制限は、ほとんどのアプリケーションで適切に機能することが証明されています。

MaxWorkerThreads と maxIoThreads

ASP.NET では、次の 2 つの構成設定を使用して、使用されるワーカー スレッドと完了スレッドの最大数を制限します。

<processModel maxWorkerThreads="20" maxIoThreads="20">

maxWorkerThreadsパラメーターと maxIoThreads パラメーターには、暗黙的に CPU の数が乗算されます。 たとえば、プロセッサが 2 つある場合、ワーカー スレッドの最大数は 2 * です maxWorkerThreads

MinFreeThreads と minLocalRequestFreeThreads

ASP.NET には、リモート要求またはローカル要求を開始するために使用できるワーカー スレッドと完了ポート スレッドの数を決定する次の構成設定も含まれています。

<httpRuntime minFreeThreads="8" minLocalRequestFreeThreads="8">

使用可能な十分なスレッドがない場合、要求を行うために十分なスレッドが解放されるまで、要求はキューに入れられます。 そのため、ASP.NET では、次の数を超える要求が同時に実行されることはありません。

(maxWorkerThreads * CPU の数) - minFreeThreads

注:

minFreeThreadsパラメーターと minLocalRequestFreeThreads パラメーターには、CPU の数が暗黙的に乗算されません。

MinWorkerThreads

ASP.NET には、リモート要求を処理するためにすぐに使用できるワーカー スレッドの数を決定する次の構成設定も含まれています。

<processModel minWorkerThreads="1">

この設定によって制御されるスレッドは、共通言語ランタイム (CLR) の既定のスレッド チューニング機能から作成されたワーカー スレッドよりもはるかに高速な速度で作成できます。

この設定を使用すると、バックエンド サーバーの低速化、クライアント側からの要求の突然のバースト、またはキュー内の要求の数が急激に増加するなどの原因で、ASP.NET 要求キューに突然入力される可能性がある要求をサービスに ASP.NET できます。

パラメーターの minWorkerThreads 既定値は 1 です。 パラメーターの値を次の minWorkerThreads 値に設定することをお勧めします。

minWorkerThreads = maxWorkerThreads / 2

既定では、 minWorkerThreads パラメーターは 、Web.config ファイルまたは Machine.config ファイルには存在しません。 この設定には、暗黙的に CPU の数が乗算されます。

Maxconnection

パラメーターは maxconnection 、特定の IP アドレスに対して行うことができる接続の数を決定します。 パラメーターは次のように表示されます。

<connectionManagement>
    <add address="*" maxconnection="2">
    <add address="http://65.53.32.230" maxconnection="12">
</connectionManagement>

アプリケーションのコードが IP アドレスではなくホスト名でアプリケーションを参照する場合、パラメーターは次のように表示されます。

<connectionManagement>
    <add address="*" maxconnection="2">
    <add address="http://hostname" maxconnection="12">
</connectionManagement>

最後に、アプリケーションが 80 以外のポートでホストされている場合、パラメーターには、次のような標準以外のポートを URL に含める必要があります。

<connectionManagement>
    <add address="*" maxconnection="2">
    <add address="http://hostname:8080" maxconnection="12">
</connectionManagement>

この記事で前に説明したパラメーターの設定はすべてプロセス レベルです。 ただし、パラメーター設定は maxconnection AppDomain レベルに適用されます。 既定では、この設定は AppDomain レベルに適用されるため、プロセス内の各 AppDomain から特定の IP アドレスへの最大 2 つの接続を作成できます。

ExecutionTimeout

ASP.NET では、次の構成設定を使用して要求の実行時間を制限します。

<httpRuntime executionTimeout="90"/>

プロパティを使用して、この制限を Server.ScriptTimeout 設定することもできます。

注:

パラメーターの executionTimeout 値を増やす場合は、パラメーターの設定を processModelresponseDeadlockInterval 変更する必要もあります。

推奨事項

このセクションで推奨される設定は、すべてのアプリケーションで機能しない場合があります。 ただし、次の追加情報は、適切な調整を行う際に役立つ場合があります。

各 ASPX ページから 1 つの IP アドレスに対して 1 つの Web サービス呼び出しを行う場合は、次の構成設定を使用することをお勧めします。

  • パラメーターと パラメーターの値を maxWorkerThreadsmaxIoThreads100 に設定します。
  • パラメーターの値を maxconnection12*N ( N は持っている CPU の数) に設定します。
  • パラメーターの値を minFreeThreads88*N に、パラメーターを minLocalRequestFreeThreads76*N に設定します。
  • minWorkerThreads 値を 50 に設定します。 は、 minWorkerThreads 既定では構成ファイルに含まれていない点に注意してください。 追加する必要があります。

これらの推奨事項の一部には、サーバー上の CPU の数を含む単純な数式が含まれます。 数式内の CPU の数を表す変数は N です。

これらの設定では、ハイパースレッディングが有効になっている場合は、物理 CPU の数ではなく論理 CPU の数を使用する必要があります。 たとえば、ハイパースレッディングが有効な 4 プロセッサ サーバーがある場合、数式の N の値は 4 ではなく 8 になります。

注:

この構成を使用すると、100 から 88=12 であるため、CPU ごとに最大 12 個の ASP.NET 要求を同時に実行できます。 そのため、少なくとも 88*N 個の ワーカー スレッドと 88*N 完了ポート スレッドを他の用途 (Web サービス コールバックなど) で使用できます。

たとえば、4 つのプロセッサとハイパースレッディングが有効なサーバーがあるとします。 これらの数式に基づいて、この記事で説明する構成設定に次の値を使用します。

<system.web>
    <processModel maxWorkerThreads="100" maxIoThreads="100" minWorkerThreads="50"/>
    <httpRuntime minFreeThreads="704" minLocalRequestFreeThreads="608"/>
</system.web>
<system.net>
    <connectionManagement>
        <add address="[ProvideIPHere]" maxconnection="96"/>
    </connectionManagement>
</system.net>

また、この構成を使用する場合、各 AppDomain の IP アドレスごとに CPU ごとに 12 の接続を使用できます。 したがって、次のシナリオでは、要求が接続を待機していて、 が使い果たされない場合 ThreadPool に、ほとんど競合が発生しません。

  • Web は 1 つのアプリケーション (AppDomain) のみをホストします。
  • ASPX ページの各要求は、1 つの Web サービス要求を行います。
  • すべての要求が同じ IP アドレスに送信されます。

ただし、この構成を使用すると、次のいずれかのシナリオで使用される接続が多すぎる可能性があります。

  • 要求は複数の IP アドレスに対して行われます。
  • 要求はリダイレクトされます (302 状態コード)。
  • 要求には認証が必要です。
  • 要求は複数の AppDomains から行われます。

これらのシナリオでは、パラメーターに小さい値を使用し、パラメーターと minLocalRequestFreeThreads パラメーターのmaxconnection値をminFreeThreads大きくすることをお勧めします。

詳細

詳細については、「 ASP.NET パフォーマンスの向上」を参照してください。

IIS で ASP.NET と共にパフォーマンスと競合が発生している場合は、次の Microsoft ブログを参照してください。