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.
quelle
Antworten:
Wenn Sie den .Net-Client verwenden, haben Sie ihn möglicherweise nicht festgelegt
Hier ist die ursprüngliche Frage und Antwort WCF Service Throttling
Update :
Diese Konfiguration wird in der .Net-Clientanwendung ausgeführt. Sie befindet sich möglicherweise beim Start oder wann immer, jedoch vor dem Starten Ihrer Tests.
Darüber hinaus können Sie es in der Datei app.config wie folgt haben
quelle
Wenn Sie es noch nicht versucht haben, kapseln Sie Ihre serverseitigen WCF-Vorgänge in try / finally-Blöcken und fügen Sie die Protokollierung hinzu, um sicherzustellen, dass sie tatsächlich zurückkehren.
Wenn diese zeigen, dass die Operationen abgeschlossen sind, besteht mein nächster Schritt darin, auf eine niedrigere Ebene zu gehen und die tatsächliche Transportschicht zu betrachten.
Wireshark oder ein ähnliches Tool zur Paketerfassung kann an dieser Stelle sehr hilfreich sein. Ich gehe davon aus, dass dies über HTTP auf Standardport 80 läuft.
Führen Sie Wireshark auf dem Client aus. Stellen Sie in den Optionen beim Starten der Erfassung den Erfassungsfilter auf ein
tcp http and host service.example.com
, um den irrelevanten Datenverkehr zu verringern.Wenn Sie können, ändern Sie Ihren Client, um Sie über die genaue Startzeit des Anrufs und den Zeitpunkt des Timeouts zu informieren. Oder überwachen Sie es einfach genau.
Wenn Sie eine Fehlermeldung erhalten, können Sie die Wireshark-Protokolle durchsuchen, um den Beginn des Anrufs zu ermitteln. Klicken Sie mit der rechten Maustaste auf das erste Paket, auf das Ihr Client ruft (sollte etwa GET /service.svc oder POST /service.svc sein), und wählen Sie Follow TCP Stream.
Wireshark dekodiert die gesamte HTTP-Konversation, sodass Sie sicherstellen können, dass WCF tatsächlich Antworten zurücksendet.
quelle
von: http://www.codeproject.com/KB/WCF/WCF_Operation_Timeout_.aspx
quelle
Ich habe ein sehr ähnliches Problem. In der Vergangenheit war dies mit Serialisierungsproblemen verbunden. Wenn dieses Problem weiterhin besteht, können Sie überprüfen, ob Sie die zurückgegebenen Objekte korrekt serialisieren können. Insbesondere wenn Sie Linq-To-Sql-Objekte mit Beziehungen verwenden, sind Serialisierungsprobleme bekannt, wenn Sie dem übergeordneten Objekt eine Rückreferenz für ein untergeordnetes Objekt hinzufügen und diese Rückreferenz als DataMember markieren.
Sie können die Serialisierung überprüfen, indem Sie eine Konsolen-App schreiben, die Ihre Objekte mithilfe des DataContractSerializer auf der Serverseite und der von Ihrem Client verwendeten Serialisierungsmethoden serialisiert und deserialisiert. In unserer aktuellen Anwendung haben wir beispielsweise sowohl WPF- als auch Compact Framework-Clients. Ich habe eine Konsolen-App geschrieben, um zu überprüfen, ob ich mit einem DataContractSerializer serialisieren und mit einem XmlDesserializer deserialisieren kann. Sie könnten das versuchen.
Wenn Sie Linq-To-Sql-Objekte mit untergeordneten Sammlungen zurückgeben, können Sie auch sicherstellen, dass Sie diese eifrig auf der Serverseite geladen haben. Aufgrund des verzögerten Ladens werden die zurückgegebenen Objekte manchmal nicht ausgefüllt und verursachen möglicherweise das Verhalten, bei dem die Anforderung mehrmals an die Dienstmethode gesendet wird.
Wenn Sie dieses Problem gelöst haben, würde ich gerne hören, wie, weil ich auch daran festhalte. Ich habe überprüft, dass mein Problem nicht die Serialisierung ist, daher bin ich ratlos.
UPDATE: Ich bin mir nicht sicher, ob es Ihnen helfen wird, aber das Service Trace Viewer Tool hat mein Problem nach 5 Tagen sehr ähnlicher Erfahrung wie Sie gelöst. Durch das Einrichten der Ablaufverfolgung und das anschließende Betrachten des unformatierten XML habe ich die Ausnahmen gefunden, die meine Serialisierungsprobleme verursacht haben. Es bezog sich auf Linq-to-SQL-Objekte, die gelegentlich mehr untergeordnete Objekte hatten, als erfolgreich serialisiert werden konnten. Wenn Sie Ihrer Datei web.config Folgendes hinzufügen, sollte die Ablaufverfolgung aktiviert werden:
Die resultierende Datei kann mit dem Service Trace Viewer Tool oder einfach im IE geöffnet werden, um die Ergebnisse zu überprüfen.
quelle
Schließen Sie die Verbindung zum WCF-Dienst zwischen den Anforderungen? Wenn Sie dies nicht tun, sehen Sie genau diese Zeitüberschreitung (eventuell).
quelle
Ich habe gerade das Problem gelöst. Ich habe festgestellt, dass die Knoten in der App.config-Datei falsch konfiguriert wurden.
Bestätigen Sie Ihre Konfiguration im Knoten
<security>
. Der Wert für das Attribut "mode" lautet "None". Wenn Ihr Wert "Transport" ist, tritt der Fehler auf.quelle
Haben Sie versucht, mit clientVia die gesendete Nachricht mit dem SOAP-Toolkit oder ähnlichem anzuzeigen ? Dies kann hilfreich sein, um festzustellen, ob der Fehler vom Client selbst oder von einem anderen Ort stammt.
quelle
deprecated
Haben Sie die WCF-Spuren überprüft? WCF neigt dazu, Ausnahmen zu schlucken und nur die letzte Ausnahme zurückzugeben. Dies ist das Zeitlimit, das Sie erhalten, da der Endpunkt nichts Sinnvolles zurückgegeben hat.
quelle
Sie erhalten diesen Fehler auch, wenn Sie ein Objekt an den Client zurückgeben, das eine Eigenschaft vom Typ enum enthält, die nicht standardmäßig festgelegt ist und deren Aufzählung keinen Wert hat, der 0 zugeordnet ist
enum MyEnum{ a=1, b=2};
quelle
Diese Ausnahmemeldung ist anscheinend recht allgemein gehalten und kann aus verschiedenen Gründen empfangen werden. Dies ist uns beim Bereitstellen des Clients auf Windows 8.1-Computern begegnet. Unser WCF-Client wird in einem Windows-Dienst ausgeführt und fragt den WCF-Dienst kontinuierlich ab. Der Windows-Dienst wird unter einem Benutzer ausgeführt, der kein Administrator ist. Das Problem wurde behoben, indem der clientCredentialType in der WCF-Konfiguration auf "Windows" gesetzt wurde, damit die Authentifizierung wie folgt weitergeleitet werden kann:
quelle
Ich bin kein WCF-Experte, aber ich frage mich, ob Sie auf DDIS keinen DDOS-Schutz haben. Ich weiß aus Erfahrung, dass der Server nicht mehr auf die Anrufe reagiert, wenn Sie eine Reihe von gleichzeitigen Verbindungen von einem einzelnen Client zu einem Server ausführen, da er einen DDOS-Angriff vermutet. Außerdem werden die Verbindungen bis zum Timeout offen gehalten, um den Client bei seinen Angriffen zu verlangsamen.
Eine Mehrfachverbindung von verschiedenen Computern / IPs sollte jedoch kein Problem sein.
Es gibt weitere Informationen in diesem MSDN-Beitrag:
http://msdn.microsoft.com/en-us/library/bb463275.aspx
Schauen Sie sich die MaxConcurrentSession-Eigenschaft an.
quelle