2012-07-03 20 views
13

Ich habe WCF-Dienst in der Konsole mit netNamedPipeBinding Binding selbst gehostet. Der Dienst hat nur eine leere Methode Send(DataTable bulk)Warum ist MSMQ schneller als WCF QueueService?

[ServiceContract] 
public interface IWcfQueueService 
{ 
    [OperationContract] 
    void Send(DataTable bulk);  
} 
public class WcfQueueService : IWcfQueueService 
{ 
    public void Send(DataTable bulk) 
    {   
     // Here would be something like _bulks.Add(bulk); 
     // BUT, for now it is empty method and still it's slower than MSMQ 
    }  
} 

Mein Kunde bekommt 200K Eingaben von DB und verarbeiten sie mit unserer BoundedThreadPool (nur schafft, sagen wir mal, 20 Fäden). Jede Eingabe wird mit einem anderen Thread bearbeitet. Jeder Thread führt MyMethod aus und am Ende MyMethod wird das Ergebnis zu bulkManager hinzugefügt.

public void MyMethod(string input) 
{    
    var res = ProcessInput(input); 
    bulkManager.Add(res); 
} 

Wenn bulkManager ansammelt N Artikel (= bulk) er die Masse zu einem anderen Thread passieren, dass alle es tut, ist enqueue dieser Masse mit einem von zwei Verfahren:

  1. Wenn WCF aktiviert: wcfQueueService.Send(bulk);
  2. sonst, wenn MSMQ aktiviert: new MessageQueue(@".\private$\q").Send(new Message {Body = bulk});

Alle zwei Methoden funktionieren, aber MSMQ funktioniert viel schneller. Mit MSMQ-Client verwaltet, um etwa 80 KByte Bulks in 20 Sekunden zu verarbeiten, während mit nur 20 KB-30 KByte. Ich verstehe nicht, warum es passiert. Mein WCF läuft in verschiedenen Prozessen wie MSMQ. Außerdem speichert mein WCF nichts, es hat eine leere Methode. Warum MSMQ WCF gewinnt?

Aktualisiert

Als leppie schlug ich .NetRemoting versucht. NetRemoting hat die Geschwindigkeit tatsächlich verbessert. Der Client hat 60K verarbeitet. Aber

  1. Es ist immer noch langsamer als MSMQ
  2. Wie ich .NET Remoting gelesen von WCF ist veraltet und WCF soll schneller sein als .NET Remoting nach this, also warum ich, dass meine Wcf langsamer ist? Vielleicht ist meine Bindung falsch?
+0

Sie werden wahrscheinlich feststellen, Remoting ist viel schneller als MSMQ (gegeben Named Pipes, nehme ich IPC auf dem lokalen Rechner). – leppie

+0

@leppie, .Net Remoting tatsächlich verbessert die Geschwindigkeit. Der Client hat 60K verarbeitet. Aber, 1 - es ist immer noch langsamer als MSMQ und 2- wie ich lese. Net Remoting wird von WCF veraltet und WCF sollte schneller sein als. NET Remoting nach http://msdn.microsoft.com/en-us/library/bb310550 .aspx # wcfperform_topic3d, also warum bekomme ich, dass mein wcf langsamer ist? – theateist

+0

@theatist: Können Sie Ihren 'InstanceContextMode' im Dienst in' Single' und 'ConcurrencyMode' in' Multiple' ändern? Dann mache einen weiteren Test. Versuchen Sie auch, die Drosselungseinstellungen anzupassen (im Servicebetrieb). –

Antwort

4

Sie vergleichen nicht mit Gleichem. Der offensichtlichste Unterschied besteht darin, dass Ihre Zeitplanung im WCF-Fall die Ausführung des gesamten Service-seitigen Channel-Stacks und Betriebsaufrufs umfasst, während Ihr direkter MSMQ-Fall nur die Zeit zum Einreihen der Payload auf der Clientseite misst. Beachten Sie, dass die Verarbeitung der Serviceseite in WCF die Deserialisierung Ihres DataTable-Objekts umfasst, was wahrscheinlich ziemlich teuer ist, wenn Ihr Massenfaktor N groß ist.

Je nachdem, wie Sie die Knots für Dienstinstanziierung und -drosselung konfiguriert haben, werden die Anforderungen vom Client möglicherweise schneller ausgeführt als vom Dienst konfiguriert, sodass die Anforderungen selbst zur Ausführung in die Warteschlange gestellt werden die Service-Seite.

Je nachdem, wie Sie Ihre Bindung konfiguriert haben, gibt es möglicherweise weitere wichtige Unterschiede, z. B. Sicherheit. Übrigens, haben Sie wirklich NetNamedPipeBinding (wie Ihre Frage angibt) und nicht NetMsmqBinding verwendet, wie der Titel zu sagen schien? Wenn dies der Fall ist, verwenden Sie die Standardbindungskonfiguration und Sie haben die totally unnecessary Verschlüsselung und Signierung jeder laufenden Bulk-Nachricht, was in Ihrem direkten MSMQ-Fall nicht passiert. Diese kryptografischen Operationen bei großen Nachrichten sind ebenfalls relativ teuer.

Ein besserer Vergleich wäre mit der als OneWay definierten WCF-Operation.

+0

der Link "total unnötig" ist tot, jede Chance, dass Sie eine Kopie des Eintrags haben? wirklich daran interessiert, das zu lesen, danke – zaitsman

0

Ich denke der Unterschied ist, was passiert in Ihrer WCF-Operation vs. was MSMQ tut, wenn es eine Anfrage akzeptiert.

Ich würde erwarten, dass die Methode, die beim Einreihen einer Nachricht mit MSMQ einfach ausgeführt wird akzeptiert die Nachricht und nichts anderes. Irgendein Back-End-Arbeiter macht das schwere Heben.

In Ihrer Operation müssen Sie die Anforderung an eine Singleton-Instanz eines Anforderungshandlers übergeben. Die Request-Handler-Instanz sollte instanziiert werden, wenn der Service "hochgefahren" ist.

Sie können auch verbesserte Leistung finden, indem Sie in .NET 4 die Parallele Aufgabenbibliothek verwenden, um Ihre Anforderungen zu parallelisieren.

1

Können Sie Beispielcode angeben, der das Verhalten anzeigt, das Sie sehen?

Ich habe meine eigenen Tests gemacht, indem ich 20.000 Nachrichten zum Senden generierte. Ich probierte beides, 20.000 mit direktem MSMQ und 20.000 mit WCF, die den MSMQ Endpunkt für mich abstrahieren.

Die 20.000 mit direkten MSMQ verwendet 64,75 Prozent der CPU-Zeit und die WCF-Version senden 20.000 Nachrichten verwendet 34,16 Prozent der CPU-Zeit (mit der Analyse-Funktion von Visual Studio Ultimate instrumentiert).

Wenn ich an meinem Ende keinen Fehler gemacht habe, war die WCF-Version fast doppelt so schnell wie die hartcodierte MSMQ-Entsprechung.