Leistungsprobleme beim Aufrufen von Webdiensten aus einer ASP.NET-Anwendung
Dieser Artikel bietet Hilfe zum Beheben von Leistungsproblemen, die auftreten, wenn Sie Webdienste von einer Microsoft ASP.NET-Anwendung aufrufen.
Originale Produktversion: ASP.NET
Ursprüngliche KB-Nummer: 821268
Symptome
Wenn Sie Webdienste von einer ASP.NET-Anwendung aufrufen, können Konflikte, schlechte Leistung und Deadlocks auftreten. Clients können berichten, dass Anforderungen nicht mehr reagieren oder die Ausführung sehr lange dauert. Wenn ein Deadlock vermutet wird, kann der Arbeitsprozess wiederverwendet werden.
Möglicherweise erhalten Sie die folgende Ausnahmefehlermeldung, wenn Sie die -Methode aufrufen HttpWebRequest.GetResponse
:
"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 für Anforderung."
Hinweis
Dieser Artikel gilt auch für Anwendungen, die Anforderungen direkt stellen HttpWebRequest
.
Ursache
Dieses Problem kann auftreten, weil ASP.NET die Anzahl von Arbeitsthreads und Abschlussportthreads einschränkt, die ein Aufruf zum Ausführen von Anforderungen verwenden kann.
In der Regel verwendet ein Aufruf eines Webdiensts einen Arbeitsthread, um den Code auszuführen, der die Anforderung sendet, und einen Abschlussportthread, 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 das verwaltete ThreadPool
Aufschöpfen, wenn mehrere Webdienstaufrufe gleichzeitig auftreten.
Angenommen, der ThreadPool
ist auf 10 Arbeitsthreads beschränkt und alle 10 Arbeitsthreads führen derzeit Code aus, der auf die Ausführung eines Rückrufs wartet. Der Rückruf kann niemals ausgeführt werden, da alle Arbeitselemente, die sich in der ThreadPool
Warteschlange befinden, blockiert werden, bis ein Thread verfügbar ist.
Eine weitere potenzielle Konfliktquelle ist der maxconnection
Parameter, den der System.Net
Namespace verwendet, um die Anzahl der Verbindungen zu begrenzen. Im Allgemeinen funktioniert dieser Grenzwert wie erwartet. Wenn viele Anwendungen jedoch versuchen, viele Anforderungen gleichzeitig an eine einzelne IP-Adresse 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 dateiMachine.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:
- Begrenzen Sie die Anzahl der ASP.NET Anforderungen, die gleichzeitig ausgeführt werden können, auf ca. 12 pro CPU.
- Ermöglichen Sie Webdienstrückrufen die freie Verwendung von
ThreadPool
Threads im . - Wählen Sie einen geeigneten Wert für den
maxconnections
Parameter aus. Ihre Auswahl basiert auf der Anzahl der verwendeten IP-Adressen und AppDomains.
Hinweis
Die Empfehlung, die Anzahl der ASP.NET Anforderungen auf 12 pro CPU zu begrenzen, ist etwas 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 zu begrenzen, 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 eingereiht, bis genügend Threads die Anforderung ausführen können. Daher führen ASP.NET nicht mehr als die folgende Anzahl von Anforderungen gleichzeitig aus:
(maxWorkerThreads
* Anzahl der CPUs) - minFreeThreads
Hinweis
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 verfügbar gemacht werden können, um eine Remoteanforderung zu verarbeiten.
<processModel minWorkerThreads="1">
Threads, die von dieser Einstellung gesteuert werden, können mit einer viel schnelleren Rate erstellt werden als Arbeitsthreads, die mit den Standardthreadoptimierungsfunktionen der Common Language Runtime (CLR) erstellt werden.
Diese Einstellung ermöglicht ASP.NET, Anforderungen zu verarbeiten, die die ASP.NET Anforderungswarteschlange aufgrund einer Verlangsamung auf einem Back-End-Server, einem plötzlichen Burst von Anforderungen vom Clientende oder ähnlichem plötzlich füllen, was zu einem plötzlichen Anstieg der Anzahl von Anforderungen in der Warteschlange führen würde.
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 weder in der Web.config-Datei noch in der Machine.config-Datei 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 sieht wie folgt aus:
<connectionManagement>
<add address="*" maxconnection="2">
<add address="http://65.53.32.230" maxconnection="12">
</connectionManagement>
Wenn der Code der Anwendung anhand des Hostnamens anstelle der IP-Adresse auf die Anwendung verweist, sollte der Parameter wie folgt aussehen:
<connectionManagement>
<add address="*" maxconnection="2">
<add address="http://hostname" maxconnection="12">
</connectionManagement>
Wenn die Anwendung an einem anderen Port als 80 gehostet wird, muss der Parameter den nicht standardmäßigen Port in der URL enthalten, ähnlich wie im folgenden Beispiel:
<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, befinden sich alle auf Prozessebene. Die maxconnection
Parametereinstellung gilt jedoch für die Ebene AppDomain. Da diese Einstellung für die AppDomain-Ebene gilt, können Sie standardmäßig 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 zu begrenzen:
<httpRuntime executionTimeout="90"/>
Sie können diesen Grenzwert auch mithilfe der Server.ScriptTimeout
-Eigenschaft festlegen.
Hinweis
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 ausführen, empfiehlt Microsoft, die folgenden Konfigurationseinstellungen zu verwenden:
- Legen Sie die Werte des
maxWorkerThreads
Parameters und desmaxIoThreads
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 denminLocalRequestFreeThreads
Parameter auf 76*N fest. - Legen Sie den Wert von
minWorkerThreads
auf 50 fest. Denken Sie daran,minWorkerThreads
dass standardmäßig nicht in der Konfigurationsdatei enthalten ist. Sie müssen sie 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.
Wenn Hyperthreading für diese Einstellungen aktiviert ist, müssen Sie die Anzahl der logischen CPUs anstelle der Anzahl der physischen CPUs verwenden. Wenn Sie beispielsweise einen Server mit vier Prozessoren mit aktiviertem Hyperthreading haben, ist der Wert von N in den Formeln 8 statt 4.
Hinweis
Wenn Sie diese Konfiguration verwenden, können Sie maximal 12 ASP.NET Anforderungen pro CPU gleichzeitig ausführen, da 100-88=12. Daher sind mindestens 88 *N Arbeitsthreads und 88* N-Abschlussportthreads für andere Zwecke (z. B. für Webdienstrückrufe) verfügbar.
Beispielsweise verfügen Sie über einen Server mit vier Prozessoren und aktiviertem Hyperthreading. Basierend auf diesen Formeln würden Sie die folgenden Werte für die in diesem Artikel erwähnten Konfigurationseinstellungen verwenden.
<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, sind außerdem 12 Verbindungen pro CPU und IP-Adresse für jede AppDomain verfügbar. Daher tritt im folgenden Szenario nur sehr wenig Konflikt auf, wenn Anforderungen auf Verbindungen warten und nicht ThreadPool
erschöpft ist:
- Das Web hostet nur eine Anwendung (AppDomain).
- Jede Anforderung für eine ASPX-Seite stellt eine Webdienstanforderung.
- Alle Anforderungen werden an dieselbe IP-Adresse gesendet.
Wenn Sie diese Konfiguration verwenden, verwenden Szenarien mit einer der folgenden Optionen wahrscheinlich zu viele Verbindungen:
- Anforderungen richten sich an mehrere IP-Adressen.
- Anforderungen werden umgeleitet (302 status Code).
- Anforderungen erfordern eine Authentifizierung.
- Anforderungen werden von mehreren AppDomains gesendet.
In diesen Szenarien empfiehlt es sich, einen niedrigeren Wert für den maxconnection
Parameter und höhere Werte für den minFreeThreads
Parameter und den minLocalRequestFreeThreads
Parameter zu verwenden.
Weitere Informationen
Weitere Informationen finden Sie unter Verbessern der leistung von ASP.NET.
Wenn sie in IIS zusammen mit ASP.NET eine schlechte Leistung und Konflikte feststellen, wechseln Sie zu den folgenden Microsoft-Blogs:
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für