Распространение сообщений от RabbitMQ среди потребителей, работающих на династиях Heroku, в виде «кругового робина» - PullRequest
0 голосов
/ 12 января 2020

У меня есть установка RabbitMQ, в которой задания отправляются на обмен, который передает их в очередь. Потребитель по очереди выполняет задания из очереди. Однако эти задания являются длительными процессами (как минимум, несколько минут). Для масштабируемости мне нужно, чтобы несколько потребителей выбирали задание из верхней части очереди и выполняли его.

Потребитель работает на династии Heroku под названием «очередь». Когда я масштабирую dyno, создается впечатление, что он создает дополнительных потребителей для каждого dyno (я могу видеть их на информационной панели RabbitMQ). Однако количество задач в очереди не изменилось - дополнительные потребители, похоже, ничего не делают. Пожалуйста, смотрите картинку ниже, чтобы понять мои настройки.

RabbitMQ setup

Я что-то здесь упускаю?

  1. Почему потребители отображаются в режиме ожидания? Из моих журналов я знаю, что по крайней мере один потребитель активно работает над задачей.
  2. Как может мой потребитель использовать 0%, когда хотя бы один потребитель определенно усердно работает.
  3. Как я могу сделать так, чтобы остальные три потребителя фактически извлекали некоторые задания из очереди?

Спасибо

РЕДАКТИРОВАТЬ: Я обнаружил, что диспетчеризация циклического обмена фактически работает, но только если дополнительные потребители уже работают, когда сообщения отправляются в очередь. Это кажется мне нелогичным поведением. Если бы я увидел большую очередь и хотел бы добавить больше потребителей, добавленные потребители ничего не будут делать, пока в очередь не будет добавлено больше элементов.

Ответы [ 2 ]

1 голос
/ 22 января 2020

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

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

Это объясняет поведение, которое вы видите:

  1. Вы создаете очередь, и доставить ему некоторые сообщения, при этом не работает ни один потребитель.
  2. Вы запускаете одного потребителя, и он предварительно извлекает все сообщения в очереди .
  3. Вы запускаете второй потребитель; хотя очередь не пуста, все сообщения помечаются как отправленные первому потребителю в ожидании подтверждения; поэтому второй потребитель бездействует.
  4. Новое сообщение поступает в очередь; он распространяется в циклическом порядке второму потребителю.

Решение состоит в том, чтобы указать basic.qos параметр для потребителя. Если для этого параметра установлено значение 1, RabbitMQ не будет отправлять сообщение потребителю, пока оно не подтвердит предыдущее сообщение; несколько потребителей с этим параметром будут получать сообщения строго циклически.

1 голос
/ 12 января 2020

Я не знаком с Heroku, поэтому я не знаю, как рабочий Heroku строит потребителя rabbitMQ, у меня просто быстрый просмотр документа Heroku.

Почему потребители отображаются как «бездействующие» '?

Я думаю, что вы имеете в виду, что очередь "простаивает"? Поскольку state в очереди относится к трафику c, это просто означает, что для потока заданий в очереди не выполняется работа. И он станет «запущенным», когда сообщение будет опубликовано в очереди.

Как может мой потребитель использовать 0%, когда хотя бы один потребитель определенно усердно работает.

То же, что и состояние очереди, из официального объяснения, consumer utilisation слишком низкое значение:

  • Было больше потребителей
  • Потребители были быстрее
  • Потребители было более высокое число предварительных выборок

В вашей ситуации prefetch_count = 0 означает отсутствие ограничений на предварительную выборку, поэтому она слишком велика. И Messages.total = Messages.unacked = 78 означает, что ваш потребитель слишком медленный, есть два много сообщений, обработанных потребителем.

Так что, если ваша скорость сообщений недостаточно велика, поле state и consumer utilisation очереди бесполезен.

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

Потому что эти неупакованные сообщения уже были предварительно выбраны существующими потребителями, они не будут использованы новыми потребителями, если вы не requeue неупакованные сообщения.

...