2010-01-22 4 views
10

Je suis nouveau aux services de la WCF et je me demandais quelle serait la meilleure façon d'aborder ce qui suit.Service WCF pour de nombreux clients simultanés et accès à la base de données

J'ai beaucoup de clients (~ 200 - ~ 500) qui font tous des demandes de mon service assez constamment pendant la journée de travail. La plupart des demandes impliquent l'interrogation d'une base de données sous-jacente pour alimenter la réponse correcte.

Ce qui m'intéresse est le nombre potentiel de connexions à la base de données engendrées par les demandes entrantes. Si tous les clients effectuent des requêtes simultanées, le serveur de base de données sera durement touché. Je voudrais éviter un nombre stupide de connexions à la base de données si possible. Serait-il préférable de restreindre le nombre de connexions simultanées au service WCF et donc réduire par inadvertance le nombre possible de connexions à la base de données? J'ai cherché à faire du service un singleton qui engendre des threads pour faire la transaction de la base de données afin que je puisse contrôler le nombre de threads, mais est-ce une surcharge et une restriction des connexions au service?

Merci beaucoup pour tout conseil.

Répondre

13

Comme Marcos déjà mentionné - WCF a une capacité d'étranglement de service intégré, que vous pouvez modifier sur le serveur. Cela empêche que votre serveur de base de données soit inondé de trop de requêtes à la fois.

Les valeurs par défaut sont:

<serviceThrottling 
     maxConcurrentCalls="16" 
     maxConcurrentSessions="10" 
     maxConcurrentInstances="26" /> 

Voir la MSDN docs on ServiceThrottlingBehavior pour plus de détails.

Cela signifie qu'un maximum de 16 appels est géré simultanément par WCF, c'est-à-dire, SI votre classe de service WCF permet plusieurs appelants à la fois!

Contrairement à Marcos, je voudrais pas recommander de faire de votre classe de service WCF un singleton. La meilleure pratique courante consiste à utiliser une classe de service WCF simple et à l'utiliser par appel, par exemple. chaque requête entrante obtiendra sa propre instance totalement séparée et nouvellement créée de votre classe de service WCF - jusqu'à un maximum tel que défini par le comportement de limitation de service et contrôlé par l'exécution de WCF. Si vous faites de votre classe de service WCF un singleton, vous devez soit définir son mode ConcurrencyMode sur Multiple, mais vous devez également faire très attention de ne pas laisser deux threads simultanés de votre classe changer les mêmes valeurs sous les uns des autres; La programmation sécurisée multi-threads est un défi majeur! Ou vous ne définissez pas le mode de simultanéité sur Multiple, mais votre instance de classe de service WCF unique et unique ne peut gérer les demandes de manière sérielle, une à la fois - pas très évolutive!

Par appel et une instance de service par requête est définitivement la solution la plus simple. Le fait que la limitation des services soit en place et avec la mise en commun des connexions ADO.NET en fait un environnement très puissant et bien agencé! Pour plus de détails, voir également Dan Rigsby's excellent blog post on WCF service throttling pour plus de détails.

+1

Merci Marc. Avec le post de Rubens et le vôtre, je suis plus confiant que je ne surchargerai pas la base de données et que je peux offrir plus de contrôle aux utilisateurs finaux à cet égard. – Andy

4

Si vous utilisez ADO pour vous connecter à votre base de données, vous devez disposer d'un mécanisme de mise en pool de connexions. Vous n'avez donc pas besoin de le faire.

S'il vous plaît, lisez cet article pour plus d'informations: ADO.NET Connection Pooling at a Glance

+1

Merci Rubens, je vais configurer mes paramètres de connexion et tester mon service. – Andy

+0

Bonjour @Andy, j'ai vu tout le post ici et était vraiment très utile pour moi. Pouvez-vous s'il vous plaît dire comment effectuer un test de stress sur le service? Y a-t-il un logiciel? –

3

Nous avons un scénario similaire et nous le résoudre en utilisant une seule conection de notre WebService à la DB et en utilisant MARS à partir SqlServer qui fonctionne parfaitement et assez rapide. Sql Server sait vraiment comment gérer les requêtes simultanées auxquelles vous ne devez pas penser.

Vous évitez avec que les frais généraux de ouvrir et fermer les connexions (obviosly que la mise en commun de connexion aide dans ce cas)

Pensez aussi à ajouter à votre service quelque chose comme web:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, 
     ConcurrencyMode = ConcurrencyMode.Multiple)] 

Et la config:

<serviceThrottling maxConcurrentCalls="100" 
maxConcurrentSessions="100" 
maxConcurrentInstances="100" /> 

Cette option est à l'intérieur

<behaviors> 
     <serviceBehaviors> 
     <behavior name="..."> 

Hope this helps :)

+1

Je ne pense pas que le InstanceContextMode = Single soit une très bonne idée - cela fait de votre classe de service un singleton, et donc un mauvais mauvais goulot d'étranglement. Je ne ferais jamais ça. Le comportement de limitation lui-même sera suffisant pour empêcher trop de connexions de base de données simultanées. –

+0

Pour nous, le singleton est parfait, si votre code n'a pas de verrou, quel est le problème à laisser courir sur le même objet? En fait, nous évitons la création de l'objet Service à chaque appel et dans les tests de stress, nous obtenons une meilleure performance avec le singleton. Notre service ne fait que des requêtes SELECT sur la base de données, nous ne voyons aucun scénario où le singleton nous pose des problèmes. Avec votre solution seulement 16 requêtes ou 10 seront traitées en même temps, quel est le problème pour laisser le serveur Sql gérer 100 ou plus?, La requête doit être très coûteuse pour éviter cela. – MarcosMeli

+1

C'est en fait exactement la suggestion dont j'avais besoin. J'ai un service WCF hébergé par un service Windows où les ressources sont limitées et je veux synchroniser l'accès à ces ressources moi-même. Le paramètre de simultanéité "Multiple" était ce qui me manquait. Merci. –

Questions connexes