Nous avons une application qui a un service WCF (* .svc) fonctionnant sur IIS7 et divers clients interrogeant le service. Le serveur exécute Win 2008 Server. Les clients exécutent Windows 2008 Server ou Windows 2003 Server. J'obtiens l'exception suivante, que j'ai vue peut en fait être liée à un grand nombre de problèmes potentiels de WCF.
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.
J'ai augmenté le délai d'expiration à 30 minutes et l'erreur s'est toujours produite. Cela me dit que quelque chose d'autre est en jeu, car la quantité de données ne pourrait jamais prendre 30 minutes à télécharger ou à télécharger.
L'erreur va et vient. Pour le moment, c'est plus fréquent. Cela n'a pas d'importance si j'ai 3 clients en cours d'exécution simultanément ou 100, cela se produit encore de temps en temps. La plupart du temps, il n'y a pas de timeouts mais j'en ai quand même quelques-uns par heure. L'erreur provient de l'une des méthodes appelées. L'une de ces méthodes n'a pas de paramètres et renvoie un peu de données. Un autre prend beaucoup de données en tant que paramètre mais s'exécute de manière asynchrone. Les erreurs proviennent toujours du client et ne font jamais référence à aucun code sur le serveur dans la trace de pile. Cela se termine toujours par:
at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
Sur le serveur: j'ai essayé (et j'ai actuellement) les paramètres de liaison suivants:
maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647"
Cela ne semble pas avoir d'impact.
J'ai essayé (et j'ai actuellement) les paramètres de limitation suivants:
<serviceThrottling maxConcurrentCalls="1500" maxConcurrentInstances="1500" maxConcurrentSessions="1500"/>
Cela ne semble pas avoir d'impact.
J'ai actuellement les paramètres suivants pour le service WCF.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]
J'ai couru avec ConcurrencyMode.Multiple
pendant un moment et l'erreur s'est toujours produite.
J'ai essayé de redémarrer IIS, de redémarrer mon serveur SQL sous-jacent, de redémarrer la machine. Tout cela ne semble pas avoir d'impact.
J'ai essayé de désactiver le pare-feu Windows. Cela ne semble pas avoir d'impact.
Sur le client, j'ai ces paramètres:
maxReceivedMessageSize="2147483647"
<system.net>
<connectionManagement>
<add address="*" maxconnection="16"/>
</connectionManagement>
</system.net>
Mon client ferme ses connexions:
var client = new MyClient();
try
{
return client.GetConfigurationOptions();
}
finally
{
client.Close();
}
J'ai modifié les paramètres de registre pour autoriser plus de connexions sortantes:
MaxConnectionsPerServer=24, MaxConnectionsPer1_0Server=32.
J'ai récemment essayé SvcTraceViewer.exe. J'ai réussi à attraper une exception du côté du client. Je vois que sa durée est de 1 minute. En regardant la trace côté serveur, je peux voir que le serveur n'est pas au courant de cette exception. La durée maximale que je peux voir est de 10 secondes.
J'ai regardé les connexions de base de données actives utilisant exec sp_who
sur le serveur. Je n'en ai que quelques-uns (2-3). J'ai regardé les connexions TCP d'un client utilisant TCPview. Il est généralement d'environ 2-3 et j'en ai vu jusqu'à 5 ou 6.
En termes simples, je suis perplexe. J'ai essayé tout ce que j'ai pu trouver, et il doit manquer quelque chose de très simple qu'un expert WCF pourrait voir. J'ai le sentiment instinctif que quelque chose bloque mes clients au bas niveau (TCP), avant que le serveur ne reçoive réellement le message et / ou que quelque chose met les messages en file d'attente au niveau du serveur et ne les laisse jamais traiter.
Si vous avez des compteurs de performance que je devrais consulter, faites-le moi savoir. (veuillez indiquer quelles valeurs sont mauvaises, car certains de ces compteurs sont difficiles à déchiffrer). En outre, comment puis-je enregistrer la taille du message WCF? Enfin, existe-t-il des outils qui me permettraient de tester le nombre de connexions que je peux établir entre mon client et mon serveur (indépendamment de mon application)
Merci pour votre temps!
Informations supplémentaires ajoutées le 20 juin:
Mon application WCF fait quelque chose de similaire à ce qui suit.
while (true)
{
Step1GetConfigurationSettingsFromServerViaWCF(); // can change between calls
Step2GetWorkUnitFromServerViaWCF();
DoWorkLocally(); // takes 5-15minutes.
Step3SendBackResultsToServerViaWCF();
}
En utilisant WireShark, j'ai vu que lorsque l'erreur se produit, j'ai cinq retransmissions TCP suivies d'une réinitialisation TCP plus tard. Je suppose que le RST vient de WCF qui tue la connexion. Le rapport d'exception que je reçois provient de l'expiration de l'étape 3.
J'ai découvert cela en regardant le flux tcp "tcp.stream eq 192". J'ai ensuite étendu mon filtre à "tcp.stream eq 192 et http et http.request.method eq POST" et j'ai vu 6 POSTs pendant ce flux. Cela semblait étrange, alors j'ai vérifié avec un autre flux tel que tcp.stream eq 100. J'avais trois POST, ce qui semble un peu plus normal car je fais trois appels. Cependant, je ferme ma connexion après chaque appel WCF, donc je me serais attendu à un appel par flux (mais je ne sais pas grand-chose sur TCP).
En enquêtant un peu plus, j'ai vidé la charge du paquet http sur le disque pour voir ce que ces six appels où.
1) Step3
2) Step1
3) Step2
4) Step3 - corrupted
5) Step1
6) Step2
Je suppose que deux clients simultanés utilisent la même connexion, c'est pourquoi j'ai vu des doublons. Cependant, j'ai encore quelques problèmes que je ne peux pas comprendre:
a) Pourquoi le paquet est-il corrompu? Fluke réseau aléatoire - peut-être? La charge est gzippée à l'aide de cet exemple de code: http://msdn.microsoft.com/en-us/library/ms751458.aspx - Le code peut-il être bogué de temps en temps lorsqu'il est utilisé simultanément? Je devrais tester sans la bibliothèque gzip.
b) Pourquoi devrais-je voir les étapes 1 et 2 s'exécuter APRÈS que l'opération corrompue a expiré? Il me semble que ces opérations n'auraient pas dû avoir lieu. Peut-être que je ne regarde pas le bon flux parce que ma compréhension de TCP est imparfaite. J'ai d'autres flux qui se produisent en même temps. Je devrais enquêter sur d'autres flux - un rapide coup d'œil sur les flux 190-194 montre que le POST Step3 a des données de charge utile appropriées (non corrompues). Me poussant à regarder à nouveau la bibliothèque gzip.