Настройка High Availabilty RabbitMQ-кластера

RabbitMQ может быть настроен для много-нодового кластера (с репликацией очередей с мастера на slave-ноды).
Отказоустойчивость может быть обеспечена добавлением round-robin лоадбалансера(например, HAProxy) впереди RabbitMQ-кластера

Для настройка High Availability необходимо настроить Cluster, а затем – репликацию/зеркалирование очередей сообщений т.к. при настройке кластера реплицируются на ноды кластера все необходимые для работы RabbitMQ данные, за исключением очередей сообщений.
Из официальной документации

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

В данном случае используется HAproxy в качестве балансировщика загрузки.
В коде приложения устанавливается IP-адрес HAProxy-сервера, который в свою очередь перенаправляет запросы на 2 RabbitMQ-сервера, находящихся в кластере и реплицирующих очереди сообщений между собой.
HAProxy мониторит состояние RabbitMQ-серверов путем проверки доступности порта RabbitMQ-службы и выбрасывает ноду из своего(не RabbitMQ) кластера( т.е. не перенаправляет на ноду запросы клиентов)
Т.е. цепочка прохождения запроса от клиента к RabbitMQ-мастер-серверу выглядит так

(если HAproxy направил клиентский запрос на мастер для этой очереди)
Либо так

(если HAproxy направил клиентский запрос на слейв для этой очереди)
Если одна из двух нод кластера неисправна, то HAproxy выбрасывает ее из кластера и соответственно оставшаяся нода является мастером и путь прохождения запроса клиента выглядит так

 

Настройка  RabbitMQ кластера из двух нод

RabbitMQ-ноды должны распознавать корректно друг друга по полным и коротким доменным именам. По умолчанию RabbitMQ использует короткие имена хостов(hostname -s)Это также справедливо при использовании инструмента rabbitmqctl
По умолчанию RabbitMQ имена каталогов в своей базе в /var/lib/rabbitmq/ создает по короткому имени хоста(hostname -s). Если имя сервера изменяется,то RabbitMQ создает новую базу с коротким именем сервера. Поэтому при изменении имени хоста не обходимо перезапустить RabbitMQ службу

app01

app02

Кластер может быть создан разными способами

Rabbitmq-ноды и CLI-инструменты(например, rabbitmqctl) используют Erlang cookie-файл для аутентификации между собой
Каждый нода кластера должна иметь такой файл с одинаковым содержимым на всех нодах кластера
Содержимое файла /var/lib/rabbitmq/.erlang.cookie на app02 должно совпадать с содержимым файла на app01
Права на файл 400, владелец/группа – rabbitmq:rabbitmq

app01

app02

Т.е. если на app02 такого файла нет,то копируем его с app01 и выставляем корректные права/владельца/группу

Запуск RabbitMQ-сервера в обычном режиме на обоих нодах

Либо

Это создает на каждой RabbitMQ ноде по НЕЗАВИСИМОМУ брокеру(broker)/кластеру

app01

app02

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

На app01 выполняем

 

Проверка действующих политик

Для того, чтобы создать кластер из двух нод мы присоединим, например, вторую ноду(app02) rabbit@app02 к первой ноде(app01) rabbit@app01
Для этого на второй ноде
Остнавливаем RabbitMQ-приложение

Присоединяем к кластеру

Запускаем RabbitMQ-приложение

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

Проверяем состояние кластера на обеих нодах

В последующем можно добавлять новые ноды в кластер в любое время, пока кластер запущен

Остановим RabbitMQ на второй ноде для прверки репликации

Проверим состояние кластера на app01

На app01 добавляем пользователя, вирт.хост, определяем права для пользователя на этот вирт.хост

Запускаем RabbitMQ на второй ноде для проверки репликации

Либо

Проверем состояние кластера на обеих нодах

Проверяем на app02 наличие созданного на app01 пользователя, вирт.хоста и прав пользователя на этот хост

т.е. репликация работает корректно

Ноды, присоединенные в кластер в любое время могут быть отсоединены с кластера или по каким-то причинам выключены/разломаны и т.д.
Все остальные ноды кластера продолжают функционировать корректно и проблемная нода будет автоматически добавлена в кластер и синхронизирована с кластером после ее запуска/восстановления

Из официальной документации

 

Выключение ноды с кластера
Например,выключим ноду rabbit@app02 с кластера ноды rabbit@app01
На app02 выполняем

Если при выключении с кластера нода app02 недоступна ,то ее можно выключить с кластера удаленно (выполняя команды на app01-ноде)

На app02-выполняем

На app01-выполняем

При этом app02-нода считает,что она все еще в кластере, поэтому ее запуск завершится с ошибкой
Нa app02 выполняем

Starting node rabbit@app02 …

Для запуска ноды app02 необходимо сбросить ее состояние

Т.е. в данный момент app02-нода работает как независимый RabbitMQ-брокер/кластер

Настройка портов firewall

Для настройки кластера достаточно открыть взаимодействие между нодами по портам
4369, 25672 по протоколу TCP
Необходимо отметить,что для настройки кластера необходимо иметь одинаковые версии RabbitMQ-сервера и Erlang на всех нодах кластера.

 

Настройка HAproxy на поддержку RabbitMQ-кластера

Важно,установить занчение параметра timeout client в rabbitmq-секции frontend больше(дольше) чем значение параметра /proc/sys/net/ipv4/tcp_keepalive_time (по умолчанию 2 часа)

В глобальных настройках Haproxy, например, может быть установлен таймаут в 50 секунд

Т.е по истечению 50 секунд соединение между клиентом и HAproxy-сервером в статусе «idle»(т.е. через него не передаются пакеты/данные) будет закрыто со стороны Haproxy
RabbitMQ-клиентам(потребителям) нужно иметь постоянное подключение к RabbitMQ-серверу,чтобы прослушивать очереди, забирать сообщения из очередей и т.д.
Решением может быть
ИЛИ
Переопределение дефолтных настроек(которые установлены на глобальном уровне) таймаута для Rabbitmq-фронтенд блока на размер таймаута, который превышает системный таймаут по поддержки tcp-соединеня путем посылки keep-alive пакетов(по умолчанию 2 часа)

ИЛИ
настройка RabbitMQ-клиентов на поддержку Heartbeat-запросов
Напрмер, установив таймаут Heartbeat-сообщений в 30 секунд(тем самым каждые 15 секунд будет отправляться heartbeat-запрос и,если 2 запроса выполнятся неуспешно, тогда(читай через 30 секунд) RabbitMQ-клиент посчитает, что соединение с сервером потеряно/разорвано и переподключится к другому серверу.
https://www.rabbitmq.com/heartbeats.html

Если оба указанных выше варианта не решают проблему закрытия «idle»-соединений, то необходимо установить как можно большие значения параметров timeout client (для frontend rabbitmq) и timeout server(для backend rabbitmq)

 

Полезные команды rabbitmqctl

Просмотр списка очередей

Просмотр списка очередей с выводом имен политик,которые применены к этим очередям

Ручная синхронизация очереди

Отмена синхронизации очереди

Проверка состояния RabbitMQ ноды

Просмотр статуса RabbitMQ-ноды

Полный отчет(включая состояние кластера, нод, политик, параметров, пользователей, вирт.хостов и т.д.)

Больше команд доступно по

 

Источник:
https://www.rabbitmq.com/clustering.html
https://www.rabbitmq.com/ha.html
https://www.rabbitmq.com/heartbeats.html
https://www.rabbitmq.com/parameters.html#policies
http://roboconf.net/en/user-guide/clustered-rabbitmq.html
https://deviantony.wordpress.com/2014/10/30/rabbitmq-and-haproxy-a-timeout-issue/ 
https://insidethecpu.com/2014/11/17/load-balancing-a-rabbitmq-cluster/

Комментирование и размещение ссылок запрещено.

Комментарии закрыты.

Яндекс.Метрика