Недавно мы столкнулись с неожиданным поведением нашего приложения на основе 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](https://i.stack.imgur.com/UhdRO.png)
Как только Сообщение5 завершается через 30 секунд с C1, Messaqe9 назначается немедленно C1 и обрабатывается без задержки
Как только сообщение 10 завершается через 30 секунд с C2, Messaqe11 назначается немедленно C2 и обрабатывается без задержки
Следовательно, нам кажется, что назначение каналов выполняется независимо для каждой очереди - это означает, что вы можете отложить выполнение, если обработка некоторых сообщений занимает много времени.
Возможно ли, что когда несколько потребителей подписываются на несколько очередей, RabbitMQ может назначить сообщение, которое будет обработано потребителем, который занят, даже если есть потребители, которые в настоящее время находятся в режиме ожидания?
Существует ли какая-либо документация, объясняющая алгоритм RabbitMQ, который выбирает, какие потребители EventingBasicConsumer.received запускает из группы потребителей?