2012-07-03 27 views
13

Tengo el servicio WCF alojado en la consola con el enlace netNamedPipeBinding. El servicio tiene un solo método vacío Send(DataTable bulk)¿Por qué MSMQ es más rápido que 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 
    }  
} 

Mi cliente obtiene 200K entradas de base de datos y procesarlo con nuestro BoundedThreadPool (sólo crea, por no decir, 20 hilos). Cada entrada se procesa con hilo diferente. Cada subproceso ejecuta MyMethod y al final de MyMethod el resultado se agrega a bulkManager.

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

Cuando bulkManager acumula N elementos (= granel) que pasan la mayor parte a otro hilo que todo lo que hace es enqueue que a granel con uno de dos métodos:

  1. Si WCF habilitado: wcfQueueService.Send(bulk);
  2. más si MSMQ habilitado: new MessageQueue(@".\private$\q").Send(new Message {Body = bulk});

Todos los dos métodos funciona, pero MSMQ funciona mucho más rápido. Con MSMQ, el cliente logra procesar aproximadamente 80 mil palabras en 20 segundos mientras que con wcf solo 20 mil a 30 mil. No entiendo por qué sucede. Mi WCF se ejecuta en un proceso diferente, como lo hace MSMQ. Además, mi WCF no almacena nada, tiene un método vacío. Entonces, ¿por qué MSMQ gana WCF?

Actualizado

Como leppie sugirió Probé .NetRemoting. NetRemoting de hecho mejoró la velocidad. El cliente procesó 60K. Pero,

  1. Es todavía más lento que MSMQ
  2. Al leer .Net Remoting está en desuso por la WCF y WCF debería ser más rápido que .Net Remoting acuerdo con this, ¿por qué me da que mi WCF es más lento? Tal vez mi enlace está mal?
+0

Probablemente encontrará que la comunicación remota es mucho más rápida que MSMQ (se le asignan conductos con nombre, supongo que IPC en la máquina local). – leppie

+0

@leppie, .Net Remoting de hecho mejoró la velocidad. El cliente procesó 60K. Pero, 1 - sigue siendo más lento que MSMQ y 2 - mientras leo. NetNet Remoting está obsoleto por WCF y WCF debería ser más rápido que .Net Remoting según http://msdn.microsoft.com/en-us/library/bb310550 .aspx # wcfperform_topic3d, entonces, ¿por qué entiendo que mi wcf es más lento? – theateist

+0

@theateist: ¿Puedes cambiar tu 'InstanceContextMode' en el servicio a' Single' y 'ConcurrencyMode' a' Multiple'? Luego haz otra prueba. También intente ajustar la configuración de aceleración (en el comportamiento del servicio). –

Respuesta

4

No está comparando cosas parecidas.

La diferencia más obvia es que en el caso WCF las temporizaciones incluyen la ejecución de toda la pila de canales del lado del servicio y la invocación de operación, mientras que su caso directo de MSMQ solo mide el tiempo para poner la carga en el lado del cliente. Tenga en cuenta que el procesamiento del lado del servicio en WCF incluye la deserialización de su objeto DataTable, que probablemente sea bastante caro si su factor de volumen N es grande.

Además, dependiendo de cómo haya configurado las perillas de establecimiento y aceleración del servicio, las solicitudes del cliente pueden realizarse más rápidamente de lo que el servicio está configurado para gestionar, lo que hace que las solicitudes se pongan en cola para su ejecución el lado del servicio.

Además, dependiendo de cómo haya configurado su encuadernación, puede haber otras diferencias significativas, como la seguridad, por ejemplo. Por cierto, ¿realmente usaste NetNamedPipeBinding (como dice tu pregunta) en lugar de NetMsmqBinding como el título parecía implicar? Si es así, usando la configuración de enlace predeterminada tendrá el cifrado totally unnecessary y la firma de cada mensaje masivo, lo que no sucede en su caso directo de MSMQ. Estas operaciones criptográficas en mensajes grandes también serán relativamente caras.

Una mejor comparación sería con la operación WCF definida como OneWay.

+0

ese enlace 'totalmente innecesario' está muerto, ¿hay alguna posibilidad de que tenga una copia de la entrada? realmente interesado en leer eso, gracias – zaitsman

0

Creo que la diferencia es lo que sucede en su Operación WCF frente a lo que hace MSMQ cuando acepta una solicitud.

Me gustaría que el método que se ejecuta al enrutar un mensaje con MSMQ simple acepte el mensaje y nada más. Algún trabajador de back-end hace el trabajo pesado.

En su operación, debe pasar la solicitud a una instancia única de un controlador de solicitudes. La instancia del controlador de solicitudes debe crearse una instancia cuando el servicio se "activa".

También puede encontrar un mejor rendimiento utilizando la Biblioteca de tareas paralelas en .NET 4 para paralelizar sus solicitudes.

1

¿Puede proporcionar un código de ejemplo que muestre el comportamiento que está observando?

Hice mis propias pruebas generando 20,000 mensajes para enviar. Intenté ambos, 20,000 con MSMQ directo y 20,000 con WCF abstrayendo el punto final de MSMQ para mí.

Los 20,000 con MSMQ directo usaban 64.75 por ciento del tiempo de CPU y la versión WCF enviando 20,000 mensajes usaba 34.16 por ciento del tiempo de CPU (equipado con la función Analizar de Visual Studio Ultimate).

A menos que haya cometido un error, la versión de WCF fue casi dos veces más rápida que el equivalente de MSMQ codificado.

Cuestiones relacionadas