2010-07-26 7 views
1

J'ai une application ASP.NET Web Forms qui effectue en interne de nombreux appels SOAP et REST aux services Web. Les appels SOAP sont effectués à l'aide du code "wrapping" propre à Microsoft. Les appels REST sont faits à partir d'un simple client REST. Ce client utilise l'option Utiliser des blocs pour disposer de toutes les ressources.WebRequest and Resources - Timeout ASP.NET

L'application fonctionne correctement pendant quelques heures, puis raccroche. Le site ne pourra plus servir les pages asp.net. J'ai testé le site en y mettant un fichier hello.htm ... ça s'est bien passé. C'est donc définitivement un problème dans l'espace moteur ASP.NET.

Il semble qu'il n'y ait plus de webrequests dans une piscine. Je pourrais être loin. Que puis-je essayer? Que devrais-je regarder? Il faut des heures pour que le problème soit reproduit. Redémarrer le site sur IIS résout le problème, mais de cource n'est pas vraiment une solution avec laquelle nous pouvons vivre.

début de la trace d'erreur et de la pile:
Erreur de serveur dans application '/'.

L'opération a expiré Description: Une exception non gérée s'est produite lors de l'exécution de la demande Web en cours. Veuillez consulter la trace de la pile pour plus d'informations sur l'erreur et son origine dans le code.

Détails de l'exception: System.Net.WebException: L'opération a expiré

Source Erreur: Une exception non gérée a été générée pendant l'exécution de la demande Web actuelle. Les informations concernant l'origine et l'emplacement de l'exception peuvent être identifiées à l'aide de la trace de la pile d'exceptions ci-dessous.

Trace de pile: [WebException: L'opération a expiré] System.Net.HttpWebRequest.GetRequestStream() 5322142 System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke (String methodName, objet [] paramètres) +103

UPDATE et PLUS d'INFO
Les appels Homegrown REST et SOAP sont tous fait synchrone.
Ils ne sont pas de longue durée, ils prennent environ 1 sec.
Les services Web sont hébergés sur un serveur Tomcat (machine différente) dans le même centre de données.
L'application .NET appelle les services SOAP et REST sur le serveur Tomcat. L'application en quelque sorte fixé lui-même après environ une heure de rester dans cet état bloqué. Pensées? Comment surveiller le .NET Threadpool? Est-ce que DefaultConnectionLimit affecte les connexions sortantes auto-initiées?

RÉSOLUTION voir les commentaires supplémentaires aux réponses et ... 1) Fermer tous les flux et les réponses/demandes de votre code Homegrown REST (oups)
2) System.Net.ServicePointManager.DefaultConnectionLimit = 96;
// valeur par défaut = 12 fois Nombre de cœurs
System.Net.ServicePointManager.MaxServicePointIdleTime = 3000;
// default = 100000 (100 secondes)
En fixant un code qui fuit et le calendrier le plus rapide tout IdleTime semble fonctionner correctement maintenant

+0

Y a-t-il des limites d'utilisation sur les services SOAP externes que vous appelez? Déterminez quel service il appelle et voyez si vous pouvez le frapper à plusieurs reprises autant de fois que vous le frappez en pratique. Toutes les pages appellent-elles ce même service? Est-ce que tous les appels SOAP échouent ou seulement celui-ci? –

+0

Je peux frapper à partir de la même boîte avec un client WinForms et une autre application Web ASP.NET (même IIS). Tous appels REST ou SOAP à partir de ce délai d'attente de site IIS. Le journal des applications l'a répertorié comme un délai WebException – BuddyJoe

+0

Comment puis-je vérifier la quantité de mémoire occupée par cette application? Je ne suis pas encore familier avec la navigation IIS 7 ou win2008 – BuddyJoe

Répondre

3

1) Utilisez-vous WebRequests asynchrones? 2) Vos appels de service Web sont-ils de longue durée (ce qui signifie qu'ils prennent beaucoup de temps à se terminer?) 3) Où le WebService est-il hébergé? Est-ce sur la même machine? 4) Où le service REST est-il hébergé? Même machine que l'application asp.net ou différente?

Lorsqu'une requête arrive sur un serveur ASP.NEt, elle est gérée sur un thread de pool de threads. Je ne suis pas sûr si ce sera un thread de port d'achèvement ou un thread de pool de threads.

De toute façon, votre application est appelée sur un thread threadpool. Sur ce thread, vous créez une requête HTTPWebRequest (HWR) sortante. Si cette requête est synchrone, elle ne doit pas prendre de thread supplémentaire. Cependant, s'il est asynchrone, il prendra un autre thread du pool pour terminer.

Maintenant, si le HWR que vous avez fait est de retour sur le même serveur, et que cette requête a besoin d'un autre thread sur le même serveur pour terminer, vous avez maintenant besoin d'un thread supplémentaire. Combinez cela avec le Webservice en prenant beaucoup de temps, et vous attacherez au moins 2 (max 3) threads par demande. Si vous envoyez beaucoup de requêtes au serveur asp.net, le serveur peut rapidement atteindre la limite maximale de threads du pool de threads. Jusqu'à présent, je suppose qu'il n'y a pas de bogues logiques dans votre code, et que vous disposez correctement de vos objets HttpWebResponse. Donc, quand il n'y a pas de thread pour finir le travail, votre HttpWebRequest peut lancer une exception de timeout.

Cela peut également se produire si vos appels Webservice backend sont sur la même machine et que vous n'avez pas augmenté le paramètre ServicePointManager.DefaultConnectionLimit à une valeur raisonnable pour votre scénario. Par exemple, si votre application asp.net s'attend à être touchée avec 200 requêtes simultanées, vous devez définir DefaultConnectionLimit = 200 + un tampon raisonnable. Le manque de connexion dans le pool de connexion peut également provoquer cela.

Solution:

Je voudrais d'abord le DefaultConnectionLimit. Si cela ne le résout pas, alors vous devrez surveiller les compteurs de performance ASP.NET et voir si le pool de threads .Net est épuisé, ce qui pourrait contribuer à l'échec des webrequests.

+0

Merci pour votre aide. Voir UPDATEs dans la question d'origine. +1 – BuddyJoe

+1

Oui, DefaultConnectionLimit affecte les connexions sortantes initiées à partir de votre application. En tant que premier test, j'essaierais d'augmenter cela pour voir si cela résout votre problème. Pour la surveillance du nombre de threads, vous pouvez voir le compteur de performance .NET CLR Verrous et threads/nbre de threads physiques courants en tant que proxy pour les # threads dans le pool de threads. Vous pouvez également suivre les compteurs de perfs asp.net qui suivent les demandes en file d'attente/demandes d'exécution, etc – feroze

+0

Appelé support Microsoft sur celui-ci et ces 2 paramètres étaient la clé- http://stackoverflow.com/questions/3363183 – BuddyJoe