2012-07-03 11 views
13

Ho un servizio WCF self-hosted in console con binding netNamedPipeBinding. Il servizio ha un solo metodo vuoto Send(DataTable bulk)Perché MSMQ è più veloce di QueueService WCF?

[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 
    }  
} 

Il mio cliente ottiene 200K ingressi da DB ed elaborare con il nostro BoundedThreadPool (crea solo, diciamo, 20 thread). Ogni input viene elaborato con thread diversi. Ogni thread esegue MyMethod e alla fine di MyMethod il risultato viene aggiunto a bulkManager.

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

Quando bulkManager accumula N elementi (= massa) che passano la maggior parte di un altro filo che non fa altro che enqueue che rinfusa con uno dei due metodi:

  1. Se wcf abilitato: wcfQueueService.Send(bulk);
  2. else se MSMQ abilitato: new MessageQueue(@".\private$\q").Send(new Message {Body = bulk});

Tutti e due i metodi funzionano, ma MSMQ funziona molto più velocemente. Con MSMQ il client riesce a processare circa 80K di massa in 20 secondi mentre con wcf solo 20K-30K di massa. Non capisco perché succede. Il mio WCF funziona in diversi processi come MSMQ. Inoltre, il mio WCF non memorizza nulla, ha un metodo vuoto. Allora, perché MSMQ vince la WCF?

Aggiornato

Come leppie suggerito ho provato .NetRemoting. NetRemoting ha effettivamente migliorato la velocità. Il cliente ha elaborato 60K. Ma,

  1. E 'ancora più lento di MSMQ
  2. Mentre leggevo .NET Remoting è deprecato da WCF e WCF dovrei essere più veloce di .NET Remoting secondo le this, quindi perché ho che la mia WCF è più lento? Forse il mio legame è sbagliato?
+0

Probabilmente il remoting è molto più veloce di MSMQ (dati i named pipe, presumo IPC sul computer locale). – leppie

+0

@leppie, .Net Il controllo remoto ha effettivamente migliorato la velocità. Il cliente ha elaborato 60K. Ma, 1 - è ancora più lento di MSMQ e 2- come leggo. Net Remoting è deprecato da WCF e WCF dovrebbe essere più veloce di .Net Remoting secondo http://msdn.microsoft.com/en-us/library/bb310550 .aspx # wcfperform_topic3d, quindi perché ho capito che il mio wcf è più lento? – theateist

+0

@theateist: puoi modificare il tuo 'InstanceContextMode' sul servizio in' Single' e 'ConcurrencyMode' in' Multiple'? Quindi fai un altro test. Prova anche a regolare le impostazioni di limitazione (nel comportamento del servizio). –

risposta

4

Non si confronta come con simili.

La differenza più ovvia è che nel caso WCF i tempi includono l'esecuzione dell'intero stack di canali sul lato servizio e l'invocazione dell'operazione, mentre il caso MSMQ diretto misura solo il tempo di accodare il carico utile sul lato client. Tenere presente che l'elaborazione del lato servizio in WCF include la deserializzazione dell'oggetto DataTable, che è probabilmente piuttosto costoso se il fattore di massa N è grande.

Inoltre, a seconda di come sono state configurate le manopole per l'istallazione e la limitazione del servizio, è possibile che le richieste del client vengano eseguite più rapidamente di quanto il servizio sia configurato per gestire, in modo che le richieste vengano accodate per l'esecuzione su il lato del servizio.

Inoltre, a seconda di come è stata configurata l'associazione, potrebbero esserci altre differenze significative, ad esempio la sicurezza. A proposito, hai davvero usato NetNamedPipeBinding (come afferma la tua domanda) piuttosto che NetMsmqBinding come il titolo sembrava implicare? In tal caso, utilizzando la configurazione di binding predefinita, verrà attivata la crittografia totally unnecessary e la firma di ciascun messaggio in blocco, che non si verifica nel caso MSMQ diretto. Queste operazioni crittografiche su messaggi di grandi dimensioni saranno anche relativamente costose.

Un confronto migliore sarebbe con l'operazione WCF definita come OneWay.

+0

che il collegamento 'totalmente inutile' è morto, ogni possibilità di avere una copia della voce? davvero interessato a leggerlo, grazie – zaitsman

0

Penso che la differenza sia ciò che accade nella tua operazione WCF rispetto a ciò che MSMQ fa quando accetta una richiesta.

Mi aspetto che il metodo che viene eseguito quando si accoda un messaggio con MSMQ semplice accetti il ​​messaggio e nient'altro. Qualche addetto al back-end fa il lavoro pesante.

Nell'operazione, è necessario passare la richiesta a un'istanza singleton di un gestore richieste. L'istanza del gestore richieste dovrebbe essere istanziata quando il servizio è "attivato".

È inoltre possibile trovare prestazioni migliorate utilizzando Task Parallel Library in .NET 4 per parallelizzare le richieste.

1

Puoi fornire un codice di esempio che mostri il comportamento che stai vedendo?

Ho eseguito i miei test generando 20.000 messaggi da inviare. Ho provato entrambi, 20.000 con MSMQ diretto e 20.000 con WCF che estraeva l'endpoint MSMQ per me.

I 20.000 con MSMQ diretto utilizzavano il 64,75 percento del tempo di CPU e la versione di WCF che inviava 20.000 messaggi utilizzava il 34,16 percento del tempo di CPU (strumentato utilizzando la funzione Analizza di Visual Studio Ultimate).

A meno che non abbia commesso un errore sul mio terminale, la versione di WCF era quasi due volte più veloce dell'equivalente MSMQ codificato.

Problemi correlati