Вопрос

У меня интересная ситуация на моих руках. В течение нескольких лет у нас было службу WCF, которая работает на IIS-коробке в нашей сети, которую мы используем для регистрации. Приложения используют BasichtTPBINDING, чтобы отправить сообщения журнала, и он входит в систему в базе данных. Большая часть входа из всех других приложений ограничена несколькими десятками журналами на операцию. Недавно мы портировали другое приложение для использования этой регистрационной службы. Это приложение входит в систему более агрессивно, чем любой другой клиенты для нашей службы ведения журнала. Он имеет операцию, которую во время ее курса может войти в течение 100 000 сообщений (это для импорта 100 000 записей через файл CSV).

При попытке найти способ сделать этот бег более эффективно, было предложено, чтобы я попробую MSMQ в очереди журнала запросов и пересылать их на сервис вместо того, чтобы приложение напрямую обменивалось с помощью службы ведения журнала (запрос Был отправлен в отдельной нити для целей производительности). Таким образом, приложение не заблокировано, пока журнал написан. Я внедрил доказательство концепции для этого решения MSMQ на моем местном компьютере, но, как я никогда не использовал MSMQ раньше, и, как я только сейчас изучаю, какое его место технологично, я нахожусь много вопросов и немногих ответов Отказ Я надеюсь, что кто-то может указать мне некоторую краткую информацию о том, как MSMQ работает так, что я могу лучше отладить это доказательство концепции, которую я написал.

Что я вижу после внедрения MSMQ:

    .
  • Мое приложение, которое отправляет журналы в MSMQ возвращается почти сразу (вместо того, чтобы ждать журнала к быть совершенным), который я хочу.
  • хотя я отправил 1000 журналов к MSMQ приложение менее 30 секунды, это займет несколько минут для Все 1000 журналов, чтобы сделать его в база данных. Похоже, что мой Очередь имеет какой-то дроссель включен, где он держит Журнал запросов, но я не знаю, как / куда проверить это.
  • Если я использую net.tcp на сервере, принимающую журналы из службы MSMQ, я получаю тонну сервисных ошибок времени ожидания, и только 90% (или около того) журналов делают его в базу данных, но если я использую Basichttpbinding, это работает надежно.

    Вот код в моем сервисе 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"));
    
    }
    
    .

    Вот код меня, создавая службу 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();
    }
    
    .

    Вот код в приложении, которое я использую для вызова службы 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)
    });
    
    .

    Я ценю любую помощь, которую кто-то может обеспечить. Я немного потерян точно, какой набор функций доступен для меня с использованием MSMQ. Я сделал 6 или около того часов исследования через Google. Большинство документов я нашел, довольно старые (2007) и являются жесткими читающими. Возможно, они ожидают, что у меня будет какой-то уровень знаний о базе по предмету.

Это было полезно?

Решение

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"
       />

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top