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

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

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

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

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

вот некоторые из проблем с которыми я столкнулся:

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

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

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

1 ответов


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

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

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

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

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

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

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

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

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

P. S.: В любом случае, если вы можете, дайте старую потребителей к пустой очереди, поэтому вам не нужно перенести сообщения вручную.

обновление:

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