RabbitMQ изменяет параметры очереди в производственной системе

Я использую RabbitMQ в качестве очереди сообщений в сервис-ориентированной архитектуре, где многие отдельные веб-службы публикуют сообщения, привязанные к очередям RabbitMQ. На эти очереди, в свою очередь, подписываются различные потребители, которые выполняют фоновую работу; довольно ванильный вариант использования RabbitMQ.

Теперь я хотел бы изменить некоторые параметры очереди (в частности, я хотел бы привязать очереди к новому обмену недоставленными сообщениями с определенным ключом маршрутизации). Моя проблема в том, что внесение этого изменения в производственную систему проблематично по нескольким причинам.

Как мне лучше всего перейти в эти новые очереди без потери сообщений в производственной системе?

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

Вот некоторые из проблем, с которыми я сталкиваюсь:

  1. Поскольку очереди RabbitMQ являются идемпотентными, разрозненные веб-службы объявляют очереди перед публикацией в них (в случае, если они еще не существуют). Как только вы измените параметры очереди (но сохраните тот же ключ маршрутизации), объявление очереди завершится ошибкой, и RabbitMQ закроет канал.

  2. Я хотел бы не терять сообщения при изменении очереди (здесь я планирую подписаться на эксклюзивного потребителя, который сохраняет сообщения, а затем повторно публикует их в новой очереди).

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


person DevinR    schedule 12.08.2014    source источник


Ответы (1)


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

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

Быстрый и грязный способ:

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

Быстрое и безопасное решение:

Это немного сложно и основано на взломе, как переносить сообщения из одной очереди в другую внутри одного виртуального хоста. Все решение работает внутри одного виртуального хоста, но требует дополнительной очереди для каждой очереди, которую вы хотите изменить. Настройте обмен недоставленными письмами в исходной очереди и укажите его для маршрутизации просроченных сообщений в новую целевую очередь. Затем примените TTL сообщения для каждой очереди к исходной очереди, установите x-message-ttl=0 (его минимальное значение см. Нет Очередь вообще обратите внимание на немедленную доставку). Оба действия могут быть выполнены через CLI или панель управления и могут быть выполнены в уже объявленной очереди. Таким образом, ваши издатели могут публиковать сообщения как обычно, и даже старые потребители могут работать, как ожидалось, впервые, но параллельно новые потребители могут потреблять сообщения из новой очереди, которая может быть предварительно объявлена ​​с новыми аргументами вручную или другим способом.

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

Намного более сложный, но более безопасный подход (для случаев, когда изменилась вся логика рабочего процесса сообщений):

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

P.S .: в любом случае выше, если вы можете, позвольте старым потребителям опустошать очереди, чтобы вам не приходилось переносить сообщения вручную.

Обновление:

Вы можете найти очень полезный плагин Shovel, особенно Динамические лопаты для перемещения сообщений между обменами и очередями, даже между разными виртуальными хостами и серверами. Это самый быстрый и безопасный способ переноса сообщений между очередями / обменами.

person pinepain    schedule 13.08.2014
comment
Спасибо за ответ. Решение vhost показалось мне самым чистым, но оно создало одну проблему: все распределенные издатели должны отслеживать, где они публикуются, и соответственно обновляться каждый раз, когда мы вносим изменения. Есть ли простой способ сделать так, чтобы они могли просто указывать на одно и то же место, а где-то еще мы могли направить его на правильный Vhost? Я не думаю, что издателям следует беспокоиться об этих деталях, если этого можно избежать. Но, возможно, это скорее вопрос системного администратора, чем вопрос RabbitMQ. - person DevinR; 14.08.2014
comment
Обычно vhost - это настраиваемая опция (или, по крайней мере, должна быть), поэтому ее изменение не должно быть проблемой. Обратите внимание: если вы не хотите (или не можете себе этого позволить) простои, просто запустите новых издателей и потребителей параллельно, а затем остановите перенос исходных сообщений со старого виртуального хоста на новый. Но если вы можете, сделайте так, чтобы ваше приложение выжило после сбоя объявления очереди на первом этапе, а затем просто примените новые изменения к производителям и потребителям. - person pinepain; 14.08.2014
comment
Я добавил решение (быстрое и безопасное решение), которое может пригодиться для внесения горячих изменений в объявление очередей, например, установить его на длительный срок, автоудаление или исключение и т. Д. Но убедитесь, что вы понимаете, что делаете. прежде чем идти по этому пути. - person pinepain; 14.08.2014
comment
Если вы не уверены в каких-либо случаях, вы можете дважды проверить решения, задав тот же вопрос в группе пользователей rabbitmq - groups.google.com/forum / #! forum / rabbitmq-Discussion и укажите ссылку на наше обсуждение. - person pinepain; 14.08.2014
comment
Я обновил свой ответ примечанием к плагину лопаты, надеюсь, это кому-то поможет. - person pinepain; 20.08.2014
comment
Обратите внимание, что x-message-ttl может быть 0, для немедленной доставки. - person André Laszlo; 20.07.2015