2009-03-25 4 views
6

J'ai un service net.tcp WCF hébergé avec le ServiceHost intégré, et lorsque je fais des tests de stress, j'ai un comportement étrange. La première fois que j'envoie un tas de demandes, on répond rapidement à 5 à 10 demandes, et les autres reviennent à environ 2 secondes d'intervalle. La deuxième fois que j'envoie les requêtes, 10 - 20 sont renvoyées rapidement, et reposent avec 2 intervalles de sencond. Les répétitions ci-dessus jusqu'à ce que je puisse obtenir plus de 100 demandes retournées rapidement, mais si j'attends une minute ou deux, l'utilisation de la mémoire du service diminue et les demandes retournent à 5-10 retour rapide.Performance de WCF avec net.tcp

Le service que je teste a un petit délai, de sorte que je peux obtenir plusieurs connexions ouvertes en même temps, si ce délai est supprimé, les demandes reviennent si rapidement que j'ai peut-être 2-5 connexions ouvertes en même temps . Ce délai consiste à simuler des connexions DB et d'autres éléments sortants. Du comportement, il semble que le ServiceHost alloue quelque chose, des threads, des instances de classe, mais je ne peux pas comprendre ce que c'est.

Je pourrais avoir une minuterie dans le client qui appelle le service pour continuer à fonctionner, mais cela semble être une mauvaise solution.

Si j'ai une charge soutenue élevée pour le service, il va croquer toutes les demandes rapidement, mais si j'ai une période de faible activité, puis une augmentation des connexions vient dans le service sera lent.

Je suppose que ma question est QU'EST-ce que le get est alloué pendant la charge élevée du service WCF, et comment puis-je configurer le service pour préallouer plus de choses qui sont allouées. J'ai fait plus de tests, et en regardant le taskmgr pour le processus, je peux voir que quand le servicehost est 'repos', il y a 10 threads ouverts, mais quand je commence à envoyer des requêtes, le thread compte. Tant que le nombre de threads est élevé, le servicehost peut traiter les demandes entrantes rapidement, mais si je suspends l'envoi des requêtes, le nombre de threads ouverts diminue et les demandes suivantes prennent plus de temps à traiter.

Maintenant, comment puis-je dire au servicehost de garder un tas de threads ouverts? Ou plus que le 10-12 qu'il garde par défaut?

Répondre

1

La chose qui détermine comment la requête peut être traitée simultanément est le ServiceThrottlingBehavior. Il y a un certain nombre de limites qui limiteront le nombre de demandes traitées. Cela dépend également de la liaison que vous utilisez, par exemple wsHttpBinding par défaut pour les sessions alors que basicHttpBinding n'utilise aucune session et la limite de session par défaut de 10 n'est pas un problème.

Voir http://msdn.microsoft.com/en-us/library/ms735114.aspx pour plus de détails.

+0

Merci, j'ai vérifié le site, et les paramètres il y a déjà dans mon fichier de configuration, avec de hautes limites, si haut que je devrais être capable de gérer toutes les connexions entrantes à la fois au lieu de premier 5-10, puis un par 2 secondes. – Kim

6

Eh bien, après beaucoup de googling, il semble que le problème est le threadpool. Le pool de threads CLR alloue quelques threads, et quand ils sont utilisés, il limite la création de nouveaux threads, et après un certain temps il libère également les threads inutilisés.

Il y a une certaine confusion au sujet d'un bogue qui signifiait que le ThreadPool n'honorait pas l'appel SetMinThreads.

http://www.michaelckennedy.net/blog/PermaLink,guid,708ee9c0-a1fd-46e5-8fa0-b1894ad6ce0f.aspx

Je ne sais pas si ce bug est résolu, ou quoi, parce que quand je modifie les paramètres ThreadPool, le problème persiste.

1

Le bogue que vous avez référencé est corrigé dans .NET 3.5 SP1.Cela peut avoir quelque chose à voir avec le problème, je pense qu'il est plus probable (beaucoup plus probable) que la limitation est votre problème plutôt que le fil comme Maurice a saisi.

<system.serviceModel> 
    <service name="???" > 
    <endpoint ... /> 
    </service> 
</system.serviceModel> 

Quelle est la limite de la limitation pour cette config "vide"? 10 sessions, 16 appels simultanés! Il faut se méfier.

est ici plus sur le filetage: http://www.michaelckennedy.net/blog/2008/08/20/ThreadPoolBugInNET20SP1IsFixed.aspx

0

Cela se sent comme un hack mais il semble résoudre votre problème. Le problème est que le threadpool prendra du temps pour démarrer un nouveau thread, ce dont vous avez vraiment besoin, ce sont les threads qui attendent en veille. Ajoutez un constructeur à votre service et définissez le nombre minimum de threads que vous souhaitez.

public YourService() 
    { 
     int workerThreads; 
     int portThreads; 
     ThreadPool.GetMinThreads(out workerThreads, out portThreads); 
     ThreadPool.SetMinThreads(200, portThreads); 
    } 
Questions connexes