Pergunta

Eu tenho uma situação interessante em minhas mãos.Há alguns anos tivemos um serviço WCF que é executado no IIS caixa em nossa rede que usamos para fazer logon.Aplicações de uso basicHttpBinding para enviar mensagens de log e regista-os numa base de dados.A maioria dos registros de todos os outros aplicativos é limitada a algumas dezenas de logs por operação.Recentemente temos portado de outro aplicativo para usar este serviço de registo.Este aplicativo registra um pouco mais agressiva do que qualquer um dos outros clientes para o nosso serviço de log.Ele tem uma operação que, durante o seu curso pode fazer mais de 100.000 mensagens (isto é para a importação de 100.000 registros através de arquivo CSV).

Na tentativa de encontrar uma maneira de fazer isso funcionar de forma mais eficiente foi sugerido que eu tente MSMQ para a fila de pedidos de registo e encaminhá-las para o serviço, em vez de ter o aplicativo se comunique diretamente com o serviço de log (a pedido foi a ser enviado em uma thread separada para fins de desempenho).Desta forma, o aplicativo não é bloqueado enquanto o log está sendo escrito.Eu tenho implementado uma prova de conceito para este MSMQ solução na minha máquina local, mas como eu nunca usei MSMQ antes, e como eu estou só agora a aprender o que o seu lugar é tecnologicamente, eu estou encontrando-me com um monte de perguntas e poucas respostas.Eu estou esperando alguém pode me apontar para algumas informações concisas sobre como MSMQ funciona para que eu possa melhor depuração esta prova de conceito, eu tenho escrito.

O que eu estou a ver, após a implementação do MSMQ:

  • Meu aplicativo que envia os logs para MSMQ retorna quase que imediatamente (em vez de esperar para que o log ser comprometido), que é o que eu quero.
  • Mesmo que eu mandei 1000 registos para o MSMQ aplicação em menos de 30 segundos, ele leva vários minutos para todos os 1000 registos para torná-lo para o de banco de dados.Parece que o meu fila tem algum tipo de limitação habilitado para onde ele está segurando o pedidos de registo, mas eu não sei como / onde para verificar isso.
  • Se eu uso net.tcp no servidor receber os logs do serviço MSMQ eu obter uma tonelada de serviço de erros de tempo de espera e apenas 90% (ou mais) dos logs de torná-lo para o banco de dados, mas se eu usar basicHttpBinding funciona de forma fiável.

Aqui está o código no meu serviço 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"));

}

Aqui está o código de mim, criando o serviço 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();
}

Aqui está o código do aplicativo que eu uso para chamar o serviço 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)
});

Agradeço qualquer ajuda que alguém pode dar.Estou um pouco perdido sobre exatamente quais recursos estão disponíveis para mim usando o MSMQ.Eu fiz 6 ou mais horas de pesquisa através do google.A maioria dos docs que eu encontrei são muito antigas (2007) e são difíceis de ler.Talvez eles estão esperando por mim para ter alguns baser nível de conhecimento sobre o assunto.

Foi útil?

Solução

O que você está vendo (se você estiver usando a net.ligação do msmq no WCF) é que é projetado para acontecer.

MSMQ, como store-and-forward facilidade, irá armazenar as mensagens em uma fila ao enviar cliente e o servidor de recebimento até que seja de rede ou de processamento de largura de banda está disponível.O que isto faz é retirar a carga do cliente (como já observado), tornando o processo assíncrono.

Você pode visualizar o status das filas usando o Monitor de Desempenho, o número de mensagens na fila de saída (no cliente) e o servidor de fila de são escritos para contadores de desempenho em tempo real e podem ser visualizados e/ou registradas.

Se o desempenho sub-ótimo, você poderia olhar para alterar o WCF as configurações de otimização para permitir mais conexões simultâneas no seu serviço de comportamentos.

exemplo:

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top