Что вызывает узкое место в этом сценарии? - PullRequest
3 голосов
/ 29 сентября 2011

Мне нужна помощь с производственной проблемой, с которой мы столкнулись.

У нас есть обработчик NServiceBus, который при обработке сообщения отправляет запрос в веб-службу asmx (.net 2.0), работающую на IIS.6.0, веб-служба затем отправляет второй http-запрос сторонней веб-службе, в среднем сторонней службе требуется 500 мсек, чтобы ответить, но нам сказали, что запросы на запуск начнутся только тогда, когда выполняется 11 одновременных запросов.

Чтобы соответствовать нашим SLA, мы должны обрабатывать 79 000 сообщений в час или ~ 1300 сообщений в минуту.При параллельной обработке 11 запросов и продолжительности в среднем 500 мс это может быть достигнуто, если мы сможем запустить одиннадцать одновременных запросов, и каждую секунду мы сможем обрабатывать около 20 сообщений.

Проблема, с которой мы сталкиваемся,что мы не можем приблизиться к этим цифрам.Наше развернутое решение заключается в следующем.У нас есть служба, которая опрашивает базу данных каждые 5 секунд, чтобы получить пакет из 100 новых сообщений, и отправляет их дистрибьютору, который распределяет нагрузку по четырем рабочим службам Windows, работающим на двух серверах.Я назову их NsbServerA и NSbServerB.Каждый рабочий сервис настроен на 2 потока, поэтому у нас всего 8 потоков.У нас есть два сервера, на которых запущены веб-службы asmx, которые я назову asmx1 и asmx2, ServerA отправляет запросы asmx1, а ServerB отправляет запросы asmx2.

Текущая пропускная способность составляет 30 000 сообщений в час, ~ 500 в минуту, ~ 8 в секунду, поэтому где-то у нас есть бутылочное горлышко, вопрос где?

Я видел эту статью http://support.microsoft.com/default.aspx?scid=kb;en-us;821268, который, по-видимому, указывает на то, что вам нужно настроить модель процесса IIS 6.0, если вы хотите совершить более одного одновременного вызова одного и того же веб-сервиса.

Цитата из статьи: «Если вы делаетеПо одному вызову веб-службы для одного IP-адреса с каждой страницы ASPX корпорация Майкрософт рекомендует использовать следующие параметры конфигурации: задайте значения параметра maxWorkerThreads и maxIoThreads равными 100. Установите значение параметра maxconnection равным 12 * N (где N - это количество процессоров, которое у вас есть.) Установите значения параметра minFreeThreads равными 88 * N, а параметра minLocalRequestFreeThreads - 76 * N. Установите значение minWorkerThreads равным 50. Помните, что minWorkerThreads по умолчанию отсутствует в файле конфигурации.. Вы должны добавить его. "

Если кто-то может шЯ хотел бы немного осветить происходящее или найти решение.

Спасибо,

Чарли

Ответы [ 3 ]

2 голосов
/ 29 сентября 2011

Одна вероятная возможность:

ServicePointManager, через который маршрутизируются все ваши веб-запросы .NET, имеет по умолчанию два одновременных соединения на объект. См. ServicePointManager.DefaultConnectionLimit .

Таким образом, если вашей сторонней веб-службе требуется в среднем 500 мс для ответа, один сервер может выполнять только четыре запроса к этой службе каждую секунду. (т.е. два одновременных запроса каждые 500 мс).

Умножьте это на два сервера, и вы получите ~ 8 сообщений в секунду.

Попробуйте установить ServicePointManager.DefaultConnectionLimit = 4; при запуске программы и посмотрите, не увеличивает ли это вашу пропускную способность.

0 голосов
/ 30 сентября 2011

Я бы предложил протестировать каждый слой системы изолированно.

В частности, сначала сделайте скидку на уровень базы данных в качестве проблемы. Я бы собрал несколько простых модульных тестов в стиле интеграции, которые обеспечивают максимальную пропускную способность базы данных, в идеале с использованием чего-то вроде Parallel.ForEach для одновременной работы нескольких сотен потоков.

Затем переместитесь вверх по слою и используйте что-то вроде заглушки, чтобы «смоделировать» вызовы базы данных и убедиться, что уровень сервиса ведет себя так, как и должен.

Тогда, по крайней мере, вы сможете сузить недостатки и справиться с ними.

0 голосов
/ 30 сентября 2011

Похоже, это может быть много вещей.

  1. Используете ли вы коммерчески доступный Standard Edition NServiceBus?Без этого ваш обработчик будет работать однопоточным.
  2. Является ли ваш веб-сервис среднего уровня асинхронным?Если второй сервисный обход выполняется синхронно, то поток будет связан и не сможет обрабатывать входящие запросы.
  3. Вы настроили достаточно рабочих потоков для обработки входящих запросов? ОБНОВЛЕНИЕ: См. Эту страницу http://msdn.microsoft.com/en-us/library/ff647787.aspx#scalenetchapt06_topic9 («Таблица 6.1: Рекомендуемые настройки потоков для уменьшения конфликтов») для рекомендаций по высокой пропускной способности.Настройки, на которые вы должны обратить внимание: minFreeThreads, maxconnection, maxWorkerThreads, minWorkerThreads.

Я бы нервничал, когда выполняю SLA с пропускной способностью 20 сообщений в секунду, если вы не можете надежно достичь этого без масштабной оптимизации.

Также, вероятно, глупый вопрос, но почему вы не можете напрямую вызвать удаленный сервис из вашего обработчика сообщений?

...