Перегрузка потребителя RabbitMQ

Я читал о принципах обмена сообщениями AMQP. (https://www.rabbitmq.com/confirms.html). Действительно полезная и хорошо написанная статья, но одна конкретная вещь о признании потребителей действительно сбивает с толку, вот цитата:

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

Потребительская перегрузка? Очередь сообщений обрабатывается и хранится в оперативной памяти брокером (если я правильно понимаю). О какой перегрузке идет речь? Есть ли у потребителя какая-то вторая очередь? Другая часть этой статьи еще более запутана:

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

Какое отставание? Как это все работает вместе? Какую часть работы выполняет потребитель (помимо потребления сообщения и его обработки, конечно)? Я думал, что брокер поддерживает очереди и пересылает сообщения, но теперь я читаю о некоторых загадочных невыполненных работах и ​​перегрузках потребителей. Это действительно сбивает с толку, может кто-нибудь объяснить это немного или хотя бы указать мне хороший источник?


person Sivich    schedule 05.04.2018    source источник


Ответы (2)


Я считаю, что документация, на которую вы ссылаетесь, касается того, что, на мой взгляд, является своего рода недостатком дизайна либо в AMQP 0-9-1, либо в его реализации RabbitMQ.

Рассмотрим следующий сценарий:

  • В очереди находятся тысячи сообщений
  • Один потребитель подписывается на очередь с AutoAck=true и без установленного счетчика предварительной выборки.

Что произойдет?

Реализация RabbitMQ заключается в доставке произвольного количества сообщений клиенту, у которого нет счетчика предварительной выборки. Кроме того, с Auto-Ack количество предварительных выборок не имеет значения, поскольку сообщения подтверждаются при доставке потребителю.

Буферы в памяти. Реализации клиентского API по умолчанию для потребителя имеют буфер в памяти (в .NET это какой-то блокирующий набор (если я правильно помню). Итак, прежде чем сообщение будет обрабатывается, но после того, как сообщение получено от брокера, оно попадает в эту область хранения в памяти. Теперь недостаток дизайна заключается в этой области хранения. У потребителя нет другого выбора, кроме как принять сообщение, пришедшее от брокера, как оно есть. публикуется клиенту асинхронно. Это недостаток с Спецификация протокола AMQP (см. стр. 53).

Таким образом, каждое сообщение в очереди в этот момент будет немедленно доставлено потребителю, и потребитель будет завален сообщениями. Если предположить, что каждое сообщение небольшое, но его обработка занимает 5 минут, вполне возможно, что этот один потребитель сможет опустошить всю очередь до того, как к нему смогут подключиться другие потребители. А так как AutoAck включен, то брокер забудет об этих сообщениях сразу после доставки.

Очевидно, что это не лучший сценарий, если вы хотите, чтобы эти сообщения обрабатывались, потому что они покинули относительную безопасность брокера и теперь находятся в ОЗУ на потребляющей конечной точке. Допустим, возникло исключение, которое приводит к сбою потребляющей конечной точки — пуф, все сообщения пропали.

Как это обойти?

Вы должны отключить Auto-Ack, и, как правило, также рекомендуется установить разумное количество предварительных выборок (обычно 2-3 достаточно).

person theMayer    schedule 05.04.2018
comment
Спасибо за такой подробный ответ! Теперь это имеет гораздо больше смысла! Что произойдет, если я отключу Auto-Ack, не указав количество предварительных выборок? Будет ли потребитель по-прежнему завален сообщениями? Или я не совсем понимаю роль pre-fetch count здесь? - person Sivich; 06.04.2018
comment
Мне пришлось бы поднять голову, чтобы увидеть, но на самом деле я так думаю. Счетчик предварительной выборки больше 1 имеет смысл только в очень ограниченных случаях, когда обработка сообщения занимает примерно столько же времени, сколько и доставка (существует не так уж много вариантов использования, где это верно). Я предпочитаю без предварительной выборки. - person theMayer; 06.04.2018
comment
Возможно, вам будет полезна эта статья: Рабочие очереди (с использованием Java-клиента) - person deamon; 15.07.2020

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

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

person boran    schedule 05.04.2018