Буферизация журнала через MSMQ для веб-службы WCF - PullRequest
3 голосов
/ 17 мая 2011

У меня интересная ситуация на моих руках.Вот уже несколько лет у нас есть служба 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 г.) и их трудно прочитать.Возможно, они ожидают, что у меня будет какой-то базовый уровень знаний по этому вопросу.

1 Ответ

1 голос
/ 17 мая 2011

То, что вы видите (если вы используете привязку net.msmq на WCF), - это то, что должно произойти.

MSMQ, как средство хранения и пересылки, будет хранить сообщения в очереди на отправляющем клиенте и принимающем сервере до тех пор, пока не станет доступной пропускная способность сети или обработки. Что это делает, так это снимает нагрузку с клиента (как вы заметили), делая процесс асинхронным.

Вы можете просматривать состояния очередей с помощью Performance Monitor, количество сообщений в исходящей очереди (на клиенте) и очереди сервера записываются в счетчики производительности в реальном времени и могут просматриваться и / или регистрироваться.

Если производительность ниже оптимальной, вы можете изменить настройки регулирования WCF, чтобы обеспечить более параллельные соединения в поведении вашей службы.

, например

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...