12
votes

L'application "auto-hébergée" WCF devient insensible

Nous avons une application de console C # (.NET 4.0) qui "Hôtes auto-héberge" Deux Services WCFS: Un wshttpbinding code> et une autre utilisation BasichttpBinding code>.

Connexion à ces services, nous avons deux applications clientes distinctes: un service basé sur Silverlight qui utilise le BasichttpBinding code> et une autre application de console qui utilise le wshttpbinding code>. P>

L'application de service WCF compte généralement environ 30 utilisateurs connectés via le client Silverlight et un autre couple de connexions à partir du client d'application de la console. Ce n'est pas "à plat" par aucun moyen; Chaque client interroge le service WCF peut-être une fois toutes les 5 secondes au plus. P>

Le problème est le suivant: intermittence, l'application de service devient une réagissance. Bien que le serveur lui-même continue à exécuter (il continue d'écrire dans un fichier journal), toutes les activités de WCF (sur les deux ServiceHost code> s) apparaissent sur "saisir". Les nouvelles demandes ne sont pas traitées (bien que les connexions TCP soient acceptées). En outre, le nombre de threads consommés par l'application commence à augmenter considérablement, au taux d'un nouveau fil neuf par seconde. Le code lui-même ne fait rien avec thread code> s ou threadpool code> s, bien qu'il publiera occasionnellement un thread.sleep code> pour quelques centaines de millisecondes . P>

La chose frustrante est la nature intermittente du problème: le code fonctionne régulièrement pendant des heures, voire des jours sans aucun problème. Ensuite, sans cause apparente, cela devient soudainement insensible et le nombre de threads commence à cocher. P>

J'ai essayé simuler l'activité de l'utilisateur - connecter et déconnecter les clients, "marécager" le service avec des demandes - mais je peux Ne faites rien pour reproduire la faute. P>

Juste au cas où le problème était un étranglement WCF, j'ai ajouté ce code: P>

 ServiceThrottlingBehavior throttlingBehavior = new System.ServiceModel.Description.ServiceThrottlingBehavior
                                                           {
                                                               MaxConcurrentCalls = 512,
                                                               MaxConcurrentInstances = 8192,
                                                               MaxConcurrentSessions = 8192
                                                           };

        host.Description.Behaviors.Add(throttlingBehavior);
        host2.Description.Behaviors.Add(throttlingBehavior);


7 commentaires

Comme vous êtes dans .net4, vous pouvez prendre une décharge de votre processus à l'aide de la tâche MGR et faites glisser ce fichier de vidage dans VS et regardez des piles parallèles pour voir ce qui se passe. Espérons que C'est évident, sinon vous devrez peut-être aller à la route Windbg. (en utilisant le même fichier de vidage). Espérons que le problème se révèle quelque chose de simple, comme quelque chose d'offert que vos clients envoient cela par inadvertance sauvegardent votre file d'attente de traitement.


Fermez-vous vos clients après avoir appelé la méthode? Peut être associé Johan.Driessen.se/poststs / ...


Je suppose que vous avez essayé mais ... Avez-vous activé la collecte de (presque) tous les compteurs de performance liés à votre processus? Lorsqu'il arrive, vous pouvez comparer les données collectées ( Convention monte avec des threads? L'utilisation de la mémoire augmente plus rapidement que les fils? Et ainsi de suite ...)


Les paramètres par défaut pour la portée de la WCF ne doivent pas être modifiés, sauf si vous comprenez comment ils fonctionnent. Je vous recommanderais que vous ne les remplacez pas depuis que c'est très rarement utile. Aussi, utilisez-vous les paramètres par défaut du concurencyMode et InstanCemode pour l'hôte de service? Pour plus d'informations, lisez Cet excellent post


Un Bit de mon expertise, mais cela ressemble à une condition de course pour une ressource statique en dehors du fil principal. Le service de la WCF continuerait certainement d'accepter les connexions et de continuer à reproduire de nouveaux threads, ce qui ne reviendra jamais parce que les deux premiers pour le verrouiller. Outre le fichier journal, y a-t-il d'autres fichiers qui sont accessibles? Même l'accès "non exclusif" a donné lieu à des conditions de race dans mon expérience. Avez-vous enveloppé toutes les ressources statiques dans verrouillage (LockObject) {} blocs?


Je me souviens de trouver un problème avec des compteurs de performance, une fuite de mémoire connue. Le correctif consistait à définir les performances de diagnostics = "Off".


Le service auto-hébergé est-il exécuté sur un système d'exploitation Windows Server? Les OS non serveur ont un nombre limité de connexions entrantes simultanées (2 ou 5, je pense). Et même avec le système d'exploitation Server, si vous n'êtes pas disposé de clients (du côté du client) ou des flux (du côté du service), les connexions ouvertes s'accumuleront jusqu'à ce qu'ils soient écoulés.


4 Réponses :



2
votes

Comme indiqué plus tôt, on dirait que vous avez une condition de course. N'EST-PAS PAR N'EST PAS CHANCE VÉRIFIER SYSTÈME SYSTÈME.SERVICEMODEL.ICOMMUNICCINICATION.Stat de la connexion quelque part dans le code? Voir Article MSDN :

Checking the value of the System.ServiceModel.ICommunicationObject.State property is 
a race condition and is not recommended to determine whether to reuse or close a channel.


0 commentaires

2
votes

Merci à tous ceux qui ont commenté et répondit; Vos suggestions et vos contributions ont vraiment aidé - notamment pour confirmer qu'il ne semble pas être quelque chose de trivial que j'ai manqué.

Cependant, et légèrement frustrant, le problème semble être parti. Voici ce que j'ai changé:

  • L'application écrivait régulièrement à la console (ma méthode "WriteToTOG" avait console.writeline ainsi que d'ajouter à un fichier; c'était purement pour ma propre commodité pendant le développement). L'application était également en cours d'exécution en tant que service utilisant Firedaemon et, pour une raison quelconque, nous avons commencé à voir High CPU Time sur Conhost.exe . Donc, pour contrer cela, j'ai commenté la console.writeline .

  • En raison du processeur élevé, nous avons également augmenté les performances de la machine virtuelle que le code s'allume en lançant quelques noyaux de plus à celui-ci.

    En conséquence, l'application est maintenant beaucoup "plus silencieuse" en termes d'utilisation du CPU. Comme d'autres l'ont mentionné, il y a presque certainement une "condition de race" dans le code quelque part, mais en faisant de la machine sous-jacente plus rapidement et que le code est plus efficace, il semble presque que j'ai diminué les chances de la condition de course. Certes, le problème qui se produisait au moins une fois par jour n'est pas arrivé dans près d'une semaine.

    Juste pour être sûr, j'ai traversé le code et je suis sûr que chaque objet partagé est enveloppé dans un verrouillage où il y a une possibilité de modifier par un autre fil - même si je Je ne fais pas de filetage explicite, je suppose que le mécanisme de la WCF le fera automatiquement et il y a le potentiel d'une demande entrante d'essayer de modifier un objet tandis que quelque chose d'autre est en train de mâcher. J'aurais attendu une sorte d'exception concurrentielle si cela se produisait si cela se produisait?

    Merci encore une fois pour l'aide, et voici en espérant que le code ne tombe pas juste après que je clique sur le bouton Publier votre réponse : /


0 commentaires

0
votes

peut être son problème de filetage qui n'a rien à voir avec WCF - comme mentionné dans les messages précédents, les déclarations de verrouillage peuvent être le suspect - votre application (partie WCF ou non), peut avoir des threads ondulés, ce qui ne peut pas quitter en raison de Problème de verrouillage.

D'autre part, cela pourrait être WCF, avez-vous reçu beaucoup de succès sur votre service WCF? Essayez de l'accélérer. http://msdn.microsoft.com/fr -Us / Bibliothèque / System.ServiceModel.description.ServiceThrottlingBehavior.MaxConCurrentInstances.aspx


0 commentaires