Wir haben eine Anwendung mit einem WCF-Dienst (* .svc), der auf IIS7 ausgeführt wird, und verschiedene Clients, die den Dienst abfragen. Auf dem Server wird Win 2008 Server ausgeführt. Auf den Clients wird entweder Windows 2008 Server oder Windows 2003 Server ausgeführt. Ich erhalte die folgende Ausnahme, die ich gesehen habe und die tatsächlich mit einer großen Anzahl potenzieller WCF-Probleme zusammenhängen kann.
System.TimeoutException: The request channel timed out while waiting for a reply after 00:00:59.9320000. Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding. The time allotted to this operation may have been a portion of a longer timeout. ---> System.TimeoutException: The HTTP request to 'http://www.domain.com/WebServices/myservice.svc/gzip' has exceeded the allotted timeout of 00:01:00. The time allotted to this operation may have been a portion of a longer timeout.
Ich habe das Timeout auf 30 Minuten erhöht und der Fehler ist immer noch aufgetreten. Dies sagt mir, dass etwas anderes im Spiel ist, da das Hochladen oder Herunterladen der Datenmenge niemals 30 Minuten dauern kann.
Der Fehler kommt und geht. Im Moment ist es häufiger. Es scheint keine Rolle zu spielen, ob 3 Clients gleichzeitig oder 100 ausgeführt werden. Es tritt immer noch gelegentlich auf. Meistens gibt es keine Auszeiten, aber ich bekomme immer noch ein paar pro Stunde. Der Fehler stammt von einer der aufgerufenen Methoden. Eine dieser Methoden hat keine Parameter und gibt ein bisschen Daten zurück. Ein anderer nimmt viele Daten als Parameter auf, wird jedoch asynchron ausgeführt. Die Fehler stammen immer vom Client und verweisen niemals auf Code auf dem Server in der Stapelverfolgung. Es endet immer mit:
at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
Auf dem Server: Ich habe die folgenden Bindungseinstellungen ausprobiert (und habe sie derzeit):
maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647"
Es scheint keine Auswirkungen zu haben.
Ich habe die folgenden Drosselungseinstellungen ausprobiert (und habe sie derzeit):
<serviceThrottling maxConcurrentCalls="1500" maxConcurrentInstances="1500" maxConcurrentSessions="1500"/>
Es scheint keine Auswirkungen zu haben.
Ich habe derzeit die folgenden Einstellungen für den WCF-Dienst.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]
Ich lief ConcurrencyMode.Multiple
eine Weile mit und der Fehler trat immer noch auf.
Ich habe versucht, IIS neu zu starten, meinen zugrunde liegenden SQL Server neu zu starten und den Computer neu zu starten. All dies scheint keinen Einfluss zu haben.
Ich habe versucht, die Windows-Firewall zu deaktivieren. Es scheint keine Auswirkungen zu haben.
Auf dem Client habe ich folgende Einstellungen:
maxReceivedMessageSize="2147483647"
<system.net>
<connectionManagement>
<add address="*" maxconnection="16"/>
</connectionManagement>
</system.net>
Mein Client schließt seine Verbindungen:
var client = new MyClient();
try
{
return client.GetConfigurationOptions();
}
finally
{
client.Close();
}
Ich habe die Registrierungseinstellungen geändert, um mehr ausgehende Verbindungen zu ermöglichen:
MaxConnectionsPerServer=24, MaxConnectionsPer1_0Server=32.
Ich habe jetzt erst kürzlich SvcTraceViewer.exe ausprobiert. Ich habe es geschafft, eine Ausnahme auf Client-Seite zu fangen. Ich sehe, dass seine Dauer 1 Minute beträgt. Wenn ich mir die serverseitige Ablaufverfolgung ansehe, kann ich feststellen, dass dem Server diese Ausnahme nicht bekannt ist. Die maximale Dauer, die ich sehen kann, beträgt 10 Sekunden.
Ich habe mir aktive Datenbankverbindungen exec sp_who
auf dem Server angesehen. Ich habe nur wenige (2-3). Ich habe mir TCP-Verbindungen von einem Client mit TCPview angesehen. Es ist normalerweise ungefähr 2-3 und ich habe bis zu 5 oder 6 gesehen.
Einfach gesagt, ich bin ratlos. Ich habe alles versucht, was ich finden konnte, und muss etwas sehr Einfaches vermissen, das ein WCF-Experte sehen könnte. Ich habe das Gefühl, dass etwas meine Clients auf niedriger Ebene (TCP) blockiert, bevor der Server die Nachricht tatsächlich empfängt, und / oder dass etwas die Nachrichten auf Serverebene in die Warteschlange stellt und sie niemals verarbeiten lässt.
Wenn Sie Leistungsindikatoren haben, die ich mir ansehen sollte, lassen Sie es mich bitte wissen. (Bitte geben Sie an, welche Werte schlecht sind, da einige dieser Zähler schwer zu entschlüsseln sind.) Wie kann ich auch die WCF-Nachrichtengröße protokollieren? Gibt es schließlich Tools, mit denen ich testen kann, wie viele Verbindungen ich zwischen meinem Client und meinem Server herstellen kann (unabhängig von meiner Anwendung)?
Vielen Dank für Ihre Zeit!
Zusätzliche Informationen hinzugefügt am 20. Juni:
Meine WCF-Anwendung macht etwas Ähnliches wie das Folgende.
while (true)
{
Step1GetConfigurationSettingsFromServerViaWCF(); // can change between calls
Step2GetWorkUnitFromServerViaWCF();
DoWorkLocally(); // takes 5-15minutes.
Step3SendBackResultsToServerViaWCF();
}
Bei Verwendung von WireShark habe ich festgestellt, dass ich bei Auftreten des Fehlers fünf TCP-Neuübertragungen habe, gefolgt von einem späteren TCP-Reset. Ich vermute, der RST kommt von WCF und beendet die Verbindung. Der Ausnahmebericht, den ich erhalte, stammt aus dem Zeitlimit von Schritt 3.
Ich habe dies durch einen Blick auf den TCP-Stream "tcp.stream eq 192" entdeckt. Ich habe dann meinen Filter auf "tcp.stream eq 192 und http und http.request.method eq POST" erweitert und während dieses Streams 6 POSTs gesehen. Das schien seltsam, also habe ich mit einem anderen Stream wie tcp.stream eq 100 nachgesehen. Ich hatte drei POSTs, was etwas normaler erscheint, weil ich drei Anrufe tätige. Ich schließe meine Verbindung jedoch nach jedem WCF-Aufruf, sodass ich einen Anruf pro Stream erwartet hätte (aber ich weiß nicht viel über TCP).
Ich habe ein bisschen mehr nachgeforscht und die http-Paketlast auf die Festplatte geschrieben, um zu sehen, wo diese sechs Anrufe wo sind.
1) Step3
2) Step1
3) Step2
4) Step3 - corrupted
5) Step1
6) Step2
Ich vermute, dass zwei Clients gleichzeitig dieselbe Verbindung verwenden. Deshalb habe ich Duplikate gesehen. Ich habe jedoch noch einige weitere Probleme, die ich nicht verstehen kann:
a) Warum ist das Paket beschädigt? Zufälliger Netzwerk-Zufall - vielleicht? Das Laden wird mithilfe dieses Beispielcodes komprimiert: http://msdn.microsoft.com/en-us/library/ms751458.aspx - Kann der Code bei gleichzeitiger Verwendung gelegentlich fehlerhaft sein ? Ich sollte ohne die gzip Bibliothek testen.
b) Warum sollte Schritt 1 und Schritt 2 ausgeführt werden, nachdem das Zeitlimit für den beschädigten Vorgang abgelaufen ist? Es scheint mir, als ob diese Operationen nicht hätten stattfinden dürfen. Vielleicht schaue ich nicht auf den richtigen Stream, weil mein Verständnis von TCP fehlerhaft ist. Ich habe andere Streams, die zur gleichen Zeit auftreten. Ich sollte andere Streams untersuchen - ein kurzer Blick auf die Streams 190-194 zeigt, dass der Step3-POST über die richtigen Nutzdaten verfügt (nicht beschädigt). Drängen Sie mich, mir die gzip-Bibliothek noch einmal anzusehen.