Freigeben über


Leistungsprobleme beim Aufrufen von Webdiensten aus einer ASP.NET-Anwendung

Dieser Artikel enthält Hilfe zum Beheben der Leistungsprobleme, die auftreten, wenn Sie Aufrufe an Webdienste von einer Microsoft ASP.NET-Anwendung ausführen.

Ursprüngliche Produktversion: ASP.NET
Ursprüngliche KB-Nummer: 821268

Symptome

Wenn Sie Aufrufe an Webdienste von einer ASP.NET-Anwendung tätigen, treten möglicherweise Konflikte, schlechte Leistung und Deadlocks auf. Clients können melden, dass Anforderungen nicht mehr reagieren oder lange dauern, bis sie ausgeführt werden. Wenn ein Deadlock vermutet wird, kann der Arbeitsprozess wiederverwendet werden.

Möglicherweise wird beim Aufrufen der HttpWebRequest.GetResponse Methode die folgende Ausnahmefehlermeldung angezeigt:

"System.InvalidOperationException: Es waren nicht genügend freie Threads im ThreadPool-Objekt vorhanden, um den Vorgang abzuschließen."

Möglicherweise erhalten Sie auch die folgende Ausnahmefehlermeldung im Browser:

"HttpException (0x80004005): Timeout anfordern."

Notiz

Dieser Artikel gilt auch für Anwendungen, die Anforderungen direkt stellen HttpWebRequest .

Ursache

Dieses Problem kann auftreten, da ASP.NET die Anzahl der Arbeitsthreads und Abschlussportthreads begrenzt, die ein Aufruf zum Ausführen von Anforderungen verwenden kann.

In der Regel verwendet ein Aufruf eines Webdiensts einen Workerthread, um den Code auszuführen, der den Anforderungs- und einen Abschlussportthread sendet, um den Rückruf vom Webdienst zu empfangen. Wenn die Anforderung jedoch umgeleitet wird oder eine Authentifizierung erfordert, kann der Aufruf bis zu zwei Arbeitsthreads und zwei Abschlussportthreads verwenden. Sie können also die verwaltete ThreadPool Leistung ausschöpfen, wenn mehrere Webdienstaufrufe gleichzeitig ausgeführt werden.

Angenommen, dies ThreadPool ist auf 10 Arbeitsthreads beschränkt und dass alle 10 Arbeitsthreads derzeit Code ausführen, der auf die Ausführung eines Rückrufs wartet. Der Rückruf kann niemals ausgeführt werden, da alle Arbeitsaufgaben, die in die ThreadPool Warteschlange gestellt werden, blockiert werden, bis ein Thread verfügbar ist.

Eine weitere potenzielle Inhaltsquelle ist der maxconnection Parameter, den der System.Net Namespace verwendet, um die Anzahl der Verbindungen zu begrenzen. Im Allgemeinen funktioniert dieser Grenzwert erwartungsgemäß. Wenn viele Anwendungen jedoch versuchen, viele Anforderungen an eine einzelne IP-Adresse gleichzeitig zu senden, müssen Threads möglicherweise auf eine verfügbare Verbindung warten.

Lösung

Um diese Probleme zu beheben, können Sie die folgenden Parameter in der Datei "Machine.config " optimieren, um Ihre Situation optimal anzupassen:

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

Führen Sie die folgenden Aktionen aus, um diese Probleme erfolgreich zu beheben:

  • Beschränken Sie die Anzahl der ASP.NET Anforderungen, die gleichzeitig auf ca. 12 pro CPU ausgeführt werden können.
  • Zulassen, dass Webdienstrückrufe frei Threads in der ThreadPool.
  • Wählen Sie einen geeigneten Wert für den maxconnections Parameter aus. Basieren Sie auf der Anzahl der verwendeten IP-Adressen und AppDomains.

Notiz

Die Empfehlung, die Anzahl der ASP.NET Anforderungen auf 12 pro CPU zu beschränken, ist ein wenig willkürlich. Diese Grenze hat sich jedoch für die meisten Anwendungen als gut erwiesen.

MaxWorkerThreads und maxIoThreads

ASP.NET verwendet die folgenden beiden Konfigurationseinstellungen, um die maximale Anzahl von Arbeitsthreads und Abschlussthreads einzuschränken, die verwendet werden:

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

Der maxWorkerThreads Parameter und der maxIoThreads Parameter werden implizit mit der Anzahl der CPUs multipliziert. Wenn Sie beispielsweise über zwei Prozessoren verfügen, beträgt die maximale Anzahl von Arbeitsthreads 2 * maxWorkerThreads.

MinFreeThreads und minLocalRequestFreeThreads

ASP.NET enthält auch die folgenden Konfigurationseinstellungen, die bestimmen, wie viele Arbeitsthreads und Abschlussportthreads verfügbar sein müssen, um eine Remoteanforderung oder eine lokale Anforderung zu starten:

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

Wenn nicht genügend Threads verfügbar sind, wird die Anforderung in die Warteschlange gestellt, bis genügend Threads frei sind, um die Anforderung zu stellen. Daher werden ASP.NET nicht mehr als die folgende Anzahl von Anforderungen gleichzeitig ausführen:

(maxWorkerThreads * Anzahl der CPUs) - minFreeThreads

Notiz

Der minFreeThreads Parameter und der minLocalRequestFreeThreads Parameter werden nicht implizit mit der Anzahl der CPUs multipliziert.

MinWorkerThreads

ASP.NET enthält auch die folgende Konfigurationseinstellung, die bestimmt, wie viele Arbeitsthreads sofort für den Dienst einer Remoteanforderung zur Verfügung gestellt werden können.

<processModel minWorkerThreads="1">

Threads, die durch diese Einstellung gesteuert werden, können viel schneller erstellt werden als Arbeitsthreads, die über die Standardthreadoptimierungsfunktionen der Common Language Runtime (CLR) erstellt werden.

Diese Einstellung ermöglicht es ASP.NET, Serviceanfragen zu senden, die plötzlich die ASP.NET Anforderungswarteschlange aufgrund eines Langsamen auf einem Back-End-Server, einem plötzlichen Ausbruch von Anforderungen vom Clientende oder einer ähnlichen, die zu einem plötzlichen Anstieg der Anzahl der Anforderungen in der Warteschlange führen könnten.

Der Standardwert für den minWorkerThreads Parameter ist 1. Es wird empfohlen, den Wert für den minWorkerThreads Parameter auf den folgenden Wert festzulegen:

minWorkerThreads = maxWorkerThreads / 2

Standardmäßig ist der minWorkerThreads Parameter nicht in der Datei "Web.config " oder in der Datei "Machine.config " vorhanden. Diese Einstellung wird implizit mit der Anzahl der CPUs multipliziert.

Maxconnection

Der maxconnection Parameter bestimmt, wie viele Verbindungen mit einer bestimmten IP-Adresse hergestellt werden können. Der Parameter wird wie folgt angezeigt:

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

Wenn der Code der Anwendung anstelle der IP-Adresse auf die Anwendung verweist, sollte der Parameter wie folgt angezeigt werden:

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

Wenn die Anwendung auf einem anderen Port als 80 gehostet wird, muss der Parameter den nicht standardmäßigen Port in die URL einschließen, ähnlich wie im folgenden:

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

Die Einstellungen für die Parameter, die weiter oben in diesem Artikel erläutert werden, sind alle auf Prozessebene. Die maxconnection Parametereinstellung gilt jedoch für die AppDomain-Ebene. Da diese Einstellung standardmäßig auf die AppDomain-Ebene angewendet wird, können Sie maximal zwei Verbindungen mit einer bestimmten IP-Adresse aus jeder AppDomain in Ihrem Prozess erstellen.

ExecutionTimeout

ASP.NET verwendet die folgende Konfigurationseinstellung, um die Ausführungszeit der Anforderung einzuschränken:

<httpRuntime executionTimeout="90"/>

Sie können diesen Grenzwert auch mithilfe der Server.ScriptTimeout Eigenschaft festlegen.

Notiz

Wenn Sie den Wert des executionTimeout Parameters erhöhen, müssen Sie möglicherweise auch die processModel responseDeadlockInterval Parametereinstellung ändern.

Empfehlungen

Die in diesem Abschnitt empfohlenen Einstellungen funktionieren möglicherweise nicht für alle Anwendungen. Die folgenden zusätzlichen Informationen können Ihnen jedoch helfen, die entsprechenden Anpassungen vorzunehmen.

Wenn Sie einen Webdienstaufruf an eine einzelne IP-Adresse von jeder ASPX-Seite tätigen, empfiehlt Microsoft, die folgenden Konfigurationseinstellungen zu verwenden:

  • Legen Sie die Werte des maxWorkerThreads Parameters und des maxIoThreads Parameters auf 100 fest.
  • Legen Sie den Wert des maxconnection Parameters auf 12*N fest (wobei N die Anzahl der CPUs ist, die Sie haben).
  • Legen Sie die Werte des minFreeThreads Parameters auf 88*N und den minLocalRequestFreeThreads Parameter auf 76*N fest.
  • Legen Sie den Wert von minWorkerThreads 50 fest. Denken Sie daran, minWorkerThreads dass sie nicht standardmäßig in der Konfigurationsdatei enthalten ist. Sie müssen es hinzufügen.

Einige dieser Empfehlungen umfassen eine einfache Formel, die die Anzahl der CPUs auf einem Server umfasst. Die Variable, die die Anzahl der CPUs in den Formeln darstellt, ist N.

Für diese Einstellungen müssen Sie, wenn Hyperthreading aktiviert ist, die Anzahl der logischen CPUs anstelle der Anzahl der physischen CPUs verwenden. Wenn Sie z. B. einen Server mit vier Prozessorn mit aktiviertem Hyperthreading haben, lautet der Wert von N in den Formeln 8 anstelle von 4.

Notiz

Wenn Sie diese Konfiguration verwenden, können Sie maximal 12 ASP.NET Anforderungen pro CPU gleichzeitig ausführen, da 100-88=12. Daher stehen mindestens 88*N-Arbeitsthreads und 88*N-Abschlussportthreads für andere Zwecke zur Verfügung (z. B. für Webdienstrückrufe).

Sie verfügen beispielsweise über einen Server mit vier Prozessoren und aktiviertem Hyperthreading. Basierend auf diesen Formeln würden Sie die folgenden Werte für die Konfigurationseinstellungen verwenden, die in diesem Artikel erwähnt werden.

<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>

Wenn Sie diese Konfiguration verwenden, stehen außerdem 12 Verbindungen pro CPU pro IP-Adresse für jede AppDomain zur Verfügung. Daher tritt im folgenden Szenario sehr wenig Inhalt auf, wenn Anforderungen auf Verbindungen warten und die ThreadPool nicht erschöpft sind:

  • Das Web hoste nur eine Anwendung (AppDomain).
  • Jede Anforderung für eine ASPX-Seite stellt eine Webdienstanforderung vor.
  • Alle Anforderungen sind an dieselbe IP-Adresse.

Wenn Sie diese Konfiguration verwenden, verwenden Sie jedoch Szenarien, die eine der folgenden Szenarien umfassen, wahrscheinlich zu viele Verbindungen:

  • Anforderungen sind an mehrere IP-Adressen.
  • Anforderungen werden umgeleitet (Statuscode 302).
  • Anforderungen erfordern eine Authentifizierung.
  • Anforderungen werden von mehreren AppDomains gestellt.

In diesen Szenarien empfiehlt es sich, einen niedrigeren Wert für den Parameter und höhere Werte für den maxconnection minFreeThreads Parameter und den minLocalRequestFreeThreads Parameter zu verwenden.

Weitere Informationen

Weitere Informationen finden Sie unter "Verbessern ASP.NET Leistung".

Wenn in IIS zusammen mit ASP.NET eine schlechte Leistung und eine schlechte Leistung auftreten, gehen Sie zu den folgenden Microsoft-Blogs: