Pregunta

Tengo una situación interesante en mis manos. Durante unos años, ahora hemos tenido un servicio WCF que se ejecuta en un cuadro IIS en nuestra red que utilizamos para el registro. Las aplicaciones utilizan BASICHTTPBINDING para enviar mensajes de registro y los registra en una base de datos. La mayor parte del registro de todas las demás aplicaciones se limita a unas pocas docenas de registros por operación. Recientemente, hemos portado otra aplicación para usar este servicio de registro. Esta aplicación registra bastante más agresivamente que cualquiera de los otros clientes para nuestro servicio de registro. Tiene una operación que durante su curso podría registrar más de 100,000 mensajes (esto es para importar 100,000 registros a través del archivo CSV).

Al tratar de encontrar una manera de ejecutarlo de manera más eficiente, se sugirió que prueba MSMQ para hacer cola las solicitudes de registro y reenviarlas al servicio en lugar de que la aplicación se comunique directamente con el servicio de registro (la solicitud fue enviado enviado en un hilo separado para fines de rendimiento). De esta manera, la aplicación no está bloqueada mientras se escribe el registro. He implementado una prueba de concepto para esta solución MSMQ en mi máquina local, pero nunca antes había usado MSMQ, y como solo ahora estoy aprendiendo lo que su lugar es tecnológicamente, me estoy encontrando con muchas preguntas y pocas respuestas. . Espero que alguien pueda señalarme alguna información concisa sobre cómo funciona MSMQ para que pueda depurar mejor esta prueba del concepto que he escrito.

Qué estoy viendo después de implementar MSMQ:

  • Mi aplicación que envía los registros a MSMQ vuelve casi de inmediato (en lugar de esperar el registro para ser comprometido) que es lo que quiero.
  • a pesar de que envié 1000 troncos a la Aplicación MSMQ en menos de 30 segundos, se tarda varios minutos para Todos los 1000 registros para llegar a la base de datos. Aparece como si mi la cola tiene algún tipo de estrangulación habilitado donde está conteniendo el Las solicitudes de registro, pero no sé cómo / dónde verificar eso.
  • Si usa NET.TCP en el servidor que recibe los registros del servicio MSMQ i obtengo un montón de errores de tiempo de espera de servicio y solo el 90% (más o menos) de los registros lo llegan a la base de datos, pero si uso Basichttpbinding, funciona de manera confiable.

    Aquí está el código en mi servicio de MSMQ:

    public void QueueLog(Log log)
    {
        try
        {
            ServiceClient writeLog = getLoggingService();
    
            string exceptionText = log.Exception == null ? string.Empty : log.Exception.ToString();
            writeLog.WriteCompatibleLog(log.LoggerName, (LoggingService.Logging.LogType)log.LogType, exceptionText, log.Message, log.ApplicationName, Utility.GetAssemblyVersion(Assembly.GetCallingAssembly()),
                Utility.GetFirstIPAddress(), Utility.GetHostName(), log.Category);
        }
        catch (Exception ex)
        {
            Debug.WriteLine("LoggingServiceWrapper.DotNet Error\n\n" + ex.GetBaseException().Message + "\n\n" + ex.GetBaseException().StackTrace);
        }
    }
    
    private ServiceClient getLoggingService()
    {
        return new ServiceClient(new BasicHttpBinding(), new EndpointAddress("http://MyServer/Service.svc"));
    
    }
    

    Aquí está el código de mí creando el servicio MSMQ

    if (!MessageQueue.Exists(Properties.Settings.Default.QueueName))
    {
        MessageQueue.Create(Properties.Settings.Default.QueueName, true);
    }
    
    ServiceHost serviceHost = new ServiceHost(typeof(LoggingServiceQueue.LoggingServiceQueue), new Uri(Properties.Settings.Default.Address));
    {
        serviceHost.Open();
    
        Console.ReadLine();
    
        serviceHost.Close();
    }
    

    Aquí está el código en la aplicación que utilizo para llamar al servicio MSMQ:

    LoggingServiceQueueClient client = new LoggingServiceQueueClient(new NetMsmqBinding(NetMsmqSecurityMode.None), new EndpointAddress("net.msmq://localhost/private/Logging"));
    
    client.QueueLog(new LoggingServiceQueue.Log
    {
        LoggerName = loggerName,
        LogType = (LoggingServiceQueue.LogType)logType,
        ApplicationName = applicationName,
        Category = category,
        Exception = exception,
        Message = message,
        SourceHostName = Utility.GetHostName(),
        SourceIp = Utility.GetFirstIPAddress(),
        Version = Utility.GetAssemblyVersion(callingAssembly)
    });
    

    Aprecio cualquier ayuda que alguien pueda proporcionar. Estoy un poco perdido en exactamente qué conjunto de características me están disponibles para MSMQ. He hecho 6 o más horas de investigación a través de Google. La mayoría de los documentos que he encontrado son bastante antiguos (2007) y son una lectura dura. Tal vez están esperando que tenga algún nivel de conocimiento basador sobre el tema.

¿Fue útil?

Solución

What you're seeing (if you're using net.msmq binding on your WCF) is what is designed to happen.

MSMQ, as a store-and-forward facility, will store messages in a queue at the sending client and the receiving server until either network or processing bandwidth is available. What this does is take load off the client (as you've observed) by making the process asynchronous.

You can view the statuses of the queues using Performance Monitor, the number of messages in the outbound queue (at the client) and the server queue are written to performance counters in realtime and can be viewed and/or logged.

If the performance is sub-optimal, you could look to change the WCF throttling settings to allow more concurrent connections in your service behaviour.

e.g.

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top