Ich habe eine ASP.NET 4.0-Anwendung, die auf IIS 7.5 auf einem 64-Bit-Windows Server 2008 R2 Enterprise-Computer mit RAM, CPU, Festplatte usw. ausgeführt wird.
Bei jeder Webanforderung stellt die ASP.NET-Anwendung eine Verbindung zu einem Backend-Webdienst (über Raw-Sockets) her, der auf demselben Computer ausgeführt wird.
Problem: Es scheint etwas zu geben, das die Anzahl der gleichzeitigen Verbindungen zum Backend-Webdienst einschränkt. Verdächtigerweise liegt die Anzahl der gleichzeitigen Verbindungen bei 16.
Ich habe diesen Schlüsselartikel von Microsoft gefunden, in dem erläutert wird, wie die Einstellungen von IIS angepasst werden, um ASP.NET-Apps aufzunehmen, die viele Webdienstanforderungen stellen: http://support.microsoft.com/?id=821268#tocHeadRef
Ich folgte den Empfehlungen des Artikels, aber immer noch kein Glück. Die Einstellung, die besonders interessant ist maxconnection
, ist die Einstellung, die ich sogar auf 999 gestoßen habe.
Irgendwelche Ideen, was sonst noch Verbindungen drosseln könnte?
Hinweis: Wenn ich IIS aus dem Mix herausschneide und die Clients eine direkte Verbindung zum Backend-Webdienst herstellen, werden so viele Verbindungen wie nötig geöffnet, sodass ich mir sicher bin, dass das Backend nicht der Engpass ist. Es muss etwas in IIS / ASP.NET-Land sein.
Hier ist der relevante Abschnitt, von dem machine.config
ich sicher bin, dass er von der Anwendung gelesen wird (überprüft mit appcmd.exe
):
<system.web>
<processModel autoConfig="false" maxWorkerThreads="100" maxIoThreads="100" minWorkerThreads="50" />
<httpRuntime minFreeThreads="176" minLocalRequestFreeThreads="152"/>
<httpHandlers />
<membership>
<providers>
<add name="AspNetSqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="LocalSqlServer"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="true"
applicationName="/"
requiresUniqueEmail="false"
passwordFormat="Hashed"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="7"
minRequiredNonalphanumericCharacters="1"
passwordAttemptWindow="10"
passwordStrengthRegularExpression="" />
</providers>
</membership>
<profile>
<providers>
<add name="AspNetSqlProfileProvider" connectionStringName="LocalSqlServer" applicationName="/"
type="System.Web.Profile.SqlProfileProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</profile>
<roleManager>
<providers>
<add name="AspNetSqlRoleProvider" connectionStringName="LocalSqlServer" applicationName="/"
type="System.Web.Security.SqlRoleProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<add name="AspNetWindowsTokenRoleProvider" applicationName="/"
type="System.Web.Security.WindowsTokenRoleProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</roleManager>
</system.web>
<system.net>
<connectionManagement>
<add address="*" maxconnection="999"/>
</connectionManagement>
</system.net>
quelle
Antworten:
Die meisten der hier bereitgestellten Antworten beziehen sich auf die Anzahl der eingehenden Anforderungen an Ihren Backend-Webservice und nicht auf die Anzahl der ausgehenden Anforderungen, die Sie von Ihrer ASP.net-Anwendung an Ihren Backend-Dienst stellen können.
Es ist nicht Ihr Backend-Webservice, der Ihre Anforderungsrate hier drosselt, sondern die Anzahl der offenen Verbindungen, die Ihre aufrufende Anwendung zum selben Endpunkt (derselben URL) herstellen möchte.
Sie können diese Einschränkung aufheben, indem Sie der Datei machine.config den folgenden Konfigurationsabschnitt hinzufügen:
Sie können natürlich eine vernünftigere Anzahl auswählen, wenn Sie 50 oder 100 gleichzeitige Verbindungen wünschen. Aber das oben genannte öffnet es bis zu max. Sie können auch eine bestimmte Adresse für die oben genannte Open-Limit-Regel anstelle des '*' angeben, das alle Adressen angibt.
MSDN-Dokumentation für System.Net.connectionManagement
Eine weitere großartige Ressource zum Verständnis von ConnectManagement in .NET
Hoffe das löst dein Problem!
EDIT: Ups, ich sehe, dass Sie die in Ihrem Code oben erwähnte Verbindungsverwaltung haben. Ich werde meine obigen Informationen belassen, da sie für zukünftige Anfragen mit demselben Problem relevant sind. Bitte beachten Sie jedoch, dass sich derzeit 4 verschiedene machine.config-Dateien auf den aktuellsten Servern befinden!
Es gibt .NET Framework v2, das sowohl unter 32-Bit als auch unter 64-Bit ausgeführt wird, sowie .NET Framework v4, das sowohl unter 32-Bit als auch unter 64-Bit ausgeführt wird. Abhängig von Ihren gewählten Einstellungen für Ihren Anwendungspool können Sie eine dieser 4 verschiedenen machine.config-Dateien verwenden! Bitte überprüfen Sie alle 4 machine.config-Dateien, die sich normalerweise hier befinden:
quelle
machine.config
(64-Bit 4.0).Mir ist klar, dass die Frage vielleicht ziemlich alt ist, aber Sie sagen, dass das Backend auf demselben Server ausgeführt wird. Das heißt, an einem anderen Port, wahrscheinlich anders als am Standardport 80.
Ich habe gelesen, dass Sie bei Verwendung des Konfigurationselements "connectionManagement" die Portnummer angeben müssen, wenn diese von der Standardnummer 80 abweicht.
LINK: Die Einstellung maxConnection funktioniert möglicherweise nicht einmal autoConfig = false in ASP.NET
Zweitens, wenn Sie die Standardkonfiguration (address = "*") verwenden, die um Ihren eigenen Backend-spezifischen Wert erweitert wurde, können Sie den spezifischen Wert an die erste Stelle setzen! Andernfalls stimmt bei einer Anforderung das * zuerst überein und der Standardwert von 2 Verbindungen wird übernommen. Genau wie wenn Sie den Abschnitt in web.config verwenden.
LINK: <Entfernen> -Element für das Verbindungsmanagement (Netzwerkeinstellungen)
Hoffe es hilft jemandem.
quelle
Könnte es sein, dass Sie eine WCF-basierte Webdienstreferenz verwenden? Standardmäßig ist ServiceThrottlingBehavior.MaxConcurrentCalls 16.
Sie können versuchen, das
<serviceThrottling>
Element Ihres Dienstreferenzverhaltens zu aktualisieren(Beachten Sie, dass ich die obigen Einstellungen empfehlen würde.) Weitere Informationen zum Konfigurieren eines geeigneten Elements finden Sie unter MSDN
<behavior>
.quelle
TcpClient
(der Dienst verkauft benutzerdefinierte binäre Blobs, nicht WCF / SOAP oder ähnliches). Diese Konfigurationsoptionen scheinen rein zu beeinflussen Sie , wenn Sie verwendenServiceHost
, nichtTcpClient
; vermisse ich etwasHaben Sie versucht, den Wert der statischen DefaultConnectionLimit- Eigenschaft programmgesteuert festzulegen ?
Hier finden Sie eine gute Informationsquelle zu diesen echten Kopfschmerzen ... ASP.NET-Thread-Verwendung unter IIS 7.5, IIS 7.0 und IIS 6.0 mit Updates für Framework 4.0.
quelle
Siehe den Abschnitt "Threading" auf dieser Seite: http://msdn.microsoft.com/en-us/library/ff647786.aspx in Verbindung mit dem Abschnitt "Verbindungen".
Haben Sie versucht, das maxconnection-Attribut Ihrer processModel-Einstellung zu erhöhen?
quelle
maxconnection
das in keinem anderen Artikel zu diesem Thema erwähnt wurde: Das Attribut gilt nicht für lokale Webdienstaufrufe. In diesem speziellen Fall des Web - Service ist vor Ort, aber wir haben das gleiche Problem in einem anderen Umfeld , in dem der Dienst nicht lokal ist.minLocalRequestFreeThreads
- Dieser Arbeitsprozess verwendet diese Einstellung, um Anforderungen von localhost (bei denen eine Webanwendung einen Webdienst auf demselben Server aufruft) in die Warteschlange zu stellen, wenn die Anzahl der verfügbaren Threads im Thread-Pool unter diese Anzahl fällt. Diese Einstellung ähnelt minFreeThreads, gilt jedoch nur für Anforderungen, die localhost verwenden .minLocalRequestFreeThreads
(siehe meinemachine.config
in der Frage.Wenn es nicht in dem Webdienst oder der Anwendung oder dem Server (Apache oder IIS) definiert ist, auf dem bzw. der das Webdienst-Verbrauchsmaterial gehostet wird, können Sie bis zum Ausfall unendlich viele Verbindungen herstellen
quelle
Während ich Leistungstests durchführe, ist das Maß, nach dem ich gehe, RPS, dh wie viele Anforderungen pro Sekunde kann der Server innerhalb einer akzeptablen Latenz bedienen.
Theoretisch kann ein Server nur so viele Anforderungen gleichzeitig ausführen wie die Anzahl der Kerne.
Es sieht nicht so aus, als ob das Problem das Threading-Modell von ASP.net ist, da es möglicherweise Tausende von RPS bedienen kann. Es scheint, dass das Problem Ihre Anwendung sein könnte. Verwenden Sie Synchronisationsprimitive?
Wie hoch ist auch die Latenz Ihrer Webdienste? Sie reagieren sehr schnell (innerhalb von Mikrosekunden). Wenn nicht, sollten Sie asynchrone Anrufe in Betracht ziehen, damit Sie nicht blockieren
Wenn dies nicht funktioniert, möchten Sie Ihren Code möglicherweise mit Visual Studio oder Redgate Profiler profilieren
quelle