2009-12-02 5 views
3

Je dois obtenir le débit maximal dans mon service WCF. Dans l'un de mes tests, le service ci-dessous n'a reçu que 50k éléments de données par minute en utilisant NetTcpBinding. Une liaison déconnectée comme NetMsmqBinding pourrait-elle améliorer cette performance?Quelle liaison WCF est la plus performante?

Le service et le client utilisent WCF et s'exécutent sur la même machine.

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, 
    ConcurrencyMode = ConcurrencyMode.Multiple)] 
public class Storage : IStorage 
{ 
    protected List<int> _data = new List<int>(); 

    public void Insert(int[] data) 
    { 
     lock (_data) 
     { 
      _data.AddRange(data); 
     } 
    } 

    public int[] Get() 
    { 
     lock (_data) 
     { 
      return _data.ToArray(); 
     } 
    } 
} 

Le code ci-dessus est une version simplifiée du code actuel.

+2

Référez-vous à http://stackoverflow.com/questions/1613586/c-wcf-inter-process-communication/1613601#1613601 pour un organigramme sur la façon de sélectionner les liaisons WCF. Il ne traite pas directement de la question de la performance, mais d'autres personnes qui se penchent sur cette question peuvent trouver cela utile. –

Répondre

4

Msmq est susceptible d'être plus lent que TcpBinding.

Si vous exécutez sur la même machine, vous devez absolument utiliser NetNamedPipeBinding (IPC) qui est la liaison la plus rapide disponible.

Vous devez également vérifier comment vous sérialisez vos données. La sérialisation du tampon de protocole est beaucoup plus rapide (et plus légère) que la sérialisation binaire WCF par défaut (mais nécessite un peu de peaufinage).

+0

http://code.google.com/p/protobuf-net/wiki/Performance –

+0

Oui, c'est l'une des deux implémentations qui a un très bon support WCF. J'ai entendu que le créateur de cette lib n'est pas un total inconnu ici » –

+0

Je l'ai utilisé mais cela n'a étrangement pas amélioré les performances de mon service –

3

Si le service et le client s'exécutent sur la même machine, j'éviterais complètement le réseau en faveur d'un mécanisme IPC tel que les canaux nommés. Le trafic réseau entraîne de nombreux frais généraux qui peuvent être évités en utilisant un mécanisme IPC.

+0

+1 pour les tuyaux nommés. Honte WCF 4.0 a dû abandonner localProcessBinding aussi :( – MattC

2

Avez-vous des raisons de croire que le transport est ce qui ralentit le taux de transaction? Qu'est-ce que le profilage vous a dit? À l'heure actuelle, ce service est configuré pour être à thread unique, et a également plusieurs appels à "Get" verrouiller les uns les autres.

Comment ce service est-il appelé/utilisé? Cela aiderait-il à le rendre multi-thread? Qu'en est-il de l'utilisation d'un verrou plus sophistiqué comme un ReaderWriterLock qui permet à plusieurs appels de se produire en même temps, mais bloquer encore sur "Ajouter"? Editer: Je sais que c'est une situation simplifiée, mais le service réel bénéficierait-il des mêmes considérations?

+0

+1 pour soulever le problème –

+0

Je viens de corriger le ConcurrencyMode. Merci! –

+0

Oui, je pense que le service actuel bénéficierait aussi d'un verrou avancé –

4

Plus rapide pour un appel isolé ou pour des milliers d'appels? NetMsmq utilise la mise en file d'attente des messages MSMQ - vous placez votre message dans une file d'attente gérée par MSMQ, et le service l'obtiendra par la suite et travaillera dessus. Vous n'obtenez pas de retour instantané, les messages sont à sens unique.

NetTcp d'autre part est comme http - seulement plus rapide. Vous envoyez une demande au service et obtenez une réponse (si tout va bien) tout de suite. Aucune file d'attente de messages en soi, vos messages sont demande/réponse.

Donc, je ne pense pas que vous pouvez comparer les deux liaisons, vraiment. Ils servent des objectifs totalement différents:

  • si vous voulez par ex. rechercher un code postal et récupérer la longitude/latitude de cet emplacement, vous voulez certainement un mécanisme de demande/réponse -> utiliser netTcp

  • si vous souhaitez déposer des demandes par ex.imprimer un document, ou réorganiser une base de données, ou quelque chose de cette nature - quelque chose qui doit être tendu à la fin, mais vous n'attendez pas une réponse immédiatement (mais vous pouvez vérifier plus tard si le message a été traité correctement), puis utiliser un message système faire la queue

espoir qui rend les choses un peu plus clair - je ne pense pas que ces deux sont vraiment orientés vers le même ensemble d'opérations, de sorte que vous aurez probablement jamais à choisir entre ces deux directement :)

+0

Si vous Regardez dans mon code, et si je vous dis que chaque client utilise seulement 1 des opérations (un client insère, et un autre client obtient), je pense que nous serons d'accord qu'un MSMQ est approprié à mon service. Le problème est que je ne l'ai jamais utilisé, et je ne savais pas si c'était performant. –

+0

bien - si vous voulez "GET" quelque chose, vous devrez envoyer une demande "GET" sur le MSMQ au service. Mais comment obtenez-vous les données? Puisque MSMQ est toujours à sens unique ... vous devez presque ouvrir une autre file d'attente (de réponse) sur laquelle le service place la réponse, et le client doit aller chercher les données à partir de là. Non, je ne pense pas, MSMQ est une bonne idée pour une opération GET, en général. –

+0

Donc, si je vous comprends bien, je devrais ignorer cette méthode GET de ce service, et transformer un de mes clients dans un service qui reçoit les données, afin d'utiliser MSMQ? –

Questions connexes