NServiceBus Pub/Sub Distributor/Worker Сценарий слишком медленный
Я работаю над проверкой концепции реализации NServiceBus v4.x для работы.
Сейчас у меня два подписчика и один издатель.
Издатель может публиковать более 500 сообщений в секунду. Работает отлично.
Абонент А работает без дистрибьюторов / работников. Это единый процесс.
Абонент B работает с одним дистрибьютором, обеспечивающим количество рабочих N.
В моем тесте я попал в конечную точку, которая создает и публикует 100 000 сообщений. Я делаю это публиковать с подписчиками в автономном режиме.
Абонент А обрабатывает стабильные 100 сообщений в секунду. Подписчик B с 2+ работниками (тот же результат с 2, 3 или 4) изо всех сил пытается набрать 50 сообщений в секунду брутто среди всех работников.
В моем сценарии кажется, что рабочие (которых я увеличивал до 40 потоков на одного работника) ждут, пока дистрибьютор даст им работу.
Возможно, я что-то упустил из-за того, что распределитель будет ограничен? Все автобусы работают без ограничений.
Системная информация: Intel Core i5 M520 @ 2,40 ГГц 8 ГБ ОЗУ Жесткий диск SSD
ОБНОВЛЕНИЕ 08/06/2013: я закончил развертывание системы на набор серверов. Я испытываю те же результаты. Каждый добавляемый мной сервер снижает производительность подписчика.
Абонент B имеет дистрибьютора на одном сервере и два дополнительных сервера для рабочих. С подписчиком B и одним сервером с активным работником я испытываю ~80 сообщений / событий в секунду. Добавление другого работника на дополнительную физическую машину уменьшает это до ~50 сообщений в секунду. Также это "фиктивные сообщения". На самом деле никакой логики не происходит в обработчиках, кроме журнала сообщений через log4net. Отключение регистрации не увеличивает производительность.
Предложения?
3 ответа
Если вы масштабируете с главными / рабочими узлами NServiceBus на одном сервере, то пытаться измерить производительность бессмысленно. Один процесс с несколькими потоками всегда будет работать лучше, чем распределитель и несколько рабочих узлов на одном компьютере, потому что распределитель станет узким местом, пока все конкурируют за одни и те же вычислительные ресурсы.
Если рабочие перемещаются на отдельные серверы, это становится совершенно другой историей. Дистрибьютор очень эффективно распределяет сообщения, если это единственное, что происходит на сервере.
Попробуйте несколько серверов и посмотрите, что получится.
Вместо того, чтобы иметь фиктивный обработчик, который ничего не делает, вы можете имитировать фактическую обработку, добавляя некоторое время ожидания, скажем, 5 секунд. А потом сравнить результаты наличия подписчика и через дистрибьютора?
Масштабирование (с дистрибьютором или без него) полезно только в тех случаях, когда работа, выполняемая одной машиной, требует времени и, следовательно, помогает больше вычислительных ресурсов. Чтобы помочь с этим, следите за счетчиком производительности CriticalTime на конечной точке и, когда вам это нужно, добавьте дистрибьютора. Масштабирование с использованием распределителя, когда это необходимо, упрощается без необходимости изменения кода, просто запуская одну и ту же конечную точку в профилях распространителя и рабочего.
Вся цепочка является транзакционной. Вы платите много за это. Увеличение рабочей нагрузки на разных компьютерах на самом деле не приведет к увеличению производительности, если у вас недостаточно быстрое дисковое хранилище с кэшированием с записью для ускорения транзакций записи.
Когда ваш документ масштабируется до нескольких серверов, просто попробуйте пометить сообщения как "Экспресс", которые не выполняют транзакционные записи в очереди, и отключите MSDTC на экземпляре шины, чтобы увидеть, какая производительность возможна без транзакций. Это не очень удобно для использования, если вы не знаете, где это не является обязательным или на что способны, если у вас есть архитектура, которая не требует DTC.