RabbitMQ несколько потребителей в нескольких очередях - сообщения задерживаются из-за обработки - PullRequest
1 голос
/ 30 мая 2019

Недавно мы столкнулись с неожиданным поведением нашего приложения на основе RabbitMQ. Версия RabbitMQ - 3.6.12, и мы используем .NET Client 5.0.1

Приложение подписывается на две очереди, одну для команд, а другую для событий - мы также используем ручные подтверждения. Наше приложение настроено на 7 потребителей. У каждого есть свой канал (IModel), и у каждого свой EventingBasicConsumer В конечном итоге мы обрабатываем сообщения при запуске EventingBasicConsumer.Received.

Наше приложение должно обрабатывать сообщения как можно ближе к тому моменту, когда они направляются в очереди, и на сегодняшний день у нас не было проблем. Однако в последнее время мы видели, что когда одно из наших обрабатываемых сообщений занимает много времени, оно задерживается, когда нужно обработать другое сообщение, хотя есть много доступных потребителей (6), которые не заняты.

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

Это лучше всего проиллюстрировано на следующем примере:

  • У нас есть простое приложение-потребитель, которое подписывается на две очереди, один для команд и один для событий. Это приложение имеет 7 потребители, каждый со своим каналом и EventingBasicConsumer Мы запустить простое приложение публикации, которое публикует 20 сообщений, второй отдельно Каждое сообщение является событием, поэтому публикуется на событие очереди за исключением 5-го и 10-го сообщений, которые являются командами и отправлено в очередь команд. Обратите внимание, что каждое событие обрабатывается без задержка, тогда как команды занимают 30 секунд

  • В следующей таблице описывается то, что мы наблюдаем в связи с назначением нескольких каналов сообщениям в нескольких очередях:

enter image description here

  • Как только Сообщение5 завершается через 30 секунд с C1, Messaqe9 назначается немедленно C1 и обрабатывается без задержки Как только сообщение 10 завершается через 30 секунд с C2, Messaqe11 назначается немедленно C2 и обрабатывается без задержки

  • Следовательно, нам кажется, что назначение каналов выполняется независимо для каждой очереди - это означает, что вы можете отложить выполнение, если обработка некоторых сообщений занимает много времени.

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

Существует ли какая-либо документация, объясняющая алгоритм RabbitMQ, который выбирает, какие потребители EventingBasicConsumer.received запускает из группы потребителей?

1 Ответ

1 голос
/ 31 мая 2019

Мы исправили эту проблему.

В документации RMQ (https://www.rabbitmq.com/api-guide.html#consuming) мы сталкивались со следующим: «Каждый канал имеет свой собственный поток диспетчеризации. Для наиболее распространенного случая использования одного потребителя»).на канал, это означает, что потребители не задерживают других потребителей. Если у вас есть несколько потребителей на канал, имейте в виду, что долго работающий потребитель может задержать отправку обратных вызовов другим потребителям на этом канале ».

В нашемкод, у нас было 2 потребителя на канал, то есть потребители могли задерживать других потребителей. Мы изменили, чтобы иметь одного потребителя на канал, и это решило проблему.

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