Настройка RabbitMQ кластера для веб-приложения
Одиночный RabbitMQ — единая точка отказа. Кластер из трёх узлов с quorum queues даёт отказоустойчивость при потере одного узла без потери сообщений.
RabbitMQ кластер разделяет метаданные (exchanges, bindings, пользователи) между всеми узлами, но очереди могут быть локальными (classic) или реплицированными (quorum/stream). Для продуктива — только quorum queues.
Архитектура кластера
Load Balancer (HAProxy / Nginx)
|
┌───────────────┼───────────────┐
↓ ↓ ↓
rabbit-1:5672 rabbit-2:5672 rabbit-3:5672
rabbit-1:15672 rabbit-2:15672 rabbit-3:15672 (management)
Quorum очереди реплицируются через Raft-протокол. Кворум: 2 из 3 узлов должны подтвердить запись.
Установка на Ubuntu 22.04
# Добавляем репозиторий Erlang (версия важна — RabbitMQ 3.13 требует Erlang 26)
curl -1sLf 'https://dl.cloudsmith.io/public/rabbitmq/rabbitmq-erlang/setup.deb.sh' | bash
apt install -y erlang-base erlang-asn1 erlang-crypto erlang-eldap erlang-ftp \
erlang-inets erlang-mnesia erlang-os-mon erlang-parsetools erlang-public-key \
erlang-runtime-tools erlang-snmp erlang-ssl erlang-syntax-tools erlang-tftp \
erlang-tools erlang-xmerl
# RabbitMQ
curl -1sLf 'https://dl.cloudsmith.io/public/rabbitmq/rabbitmq-server/setup.deb.sh' | bash
apt install -y rabbitmq-server=3.13.*
systemctl enable rabbitmq-server
Конфигурация узлов
/etc/rabbitmq/rabbitmq.conf — одинаковый для всех узлов (кроме имён):
# rabbit-1 (для других узлов меняем только имя)
nodename = rabbit@rabbit-1
# Сеть
listeners.tcp.default = 5672
management.tcp.port = 15672
# Кластер — все узлы должны знать друг о друге
cluster_formation.peer_discovery_backend = rabbit_peer_discovery_classic_config
cluster_formation.classic_config.nodes.1 = rabbit@rabbit-1
cluster_formation.classic_config.nodes.2 = rabbit@rabbit-2
cluster_formation.classic_config.nodes.3 = rabbit@rabbit-3
# Алёртинг при достижении watermark памяти
vm_memory_high_watermark.relative = 0.6
vm_memory_high_watermark_paging_ratio = 0.75
disk_free_limit.relative = 1.5
# TLS
# ssl_options.cacertfile = /etc/rabbitmq/ssl/ca.crt
# ssl_options.certfile = /etc/rabbitmq/ssl/rabbit-1.crt
# ssl_options.keyfile = /etc/rabbitmq/ssl/rabbit-1.key
# Heartbeat
heartbeat = 60
# Размер frame
frame_max = 131072
# Логирование
log.file.level = warning
log.console = true
log.console.level = warning
Erlang cookie — должен быть одинаковым на всех узлах (используется для аутентификации в кластере):
# На первом узле генерируем
openssl rand -hex 32 | tr -d '\n' > /var/lib/rabbitmq/.erlang.cookie
chmod 400 /var/lib/rabbitmq/.erlang.cookie
chown rabbitmq:rabbitmq /var/lib/rabbitmq/.erlang.cookie
# Копируем на остальные узлы
scp /var/lib/rabbitmq/.erlang.cookie rabbit-2:/var/lib/rabbitmq/.erlang.cookie
scp /var/lib/rabbitmq/.erlang.cookie rabbit-3:/var/lib/rabbitmq/.erlang.cookie
Присоединение узлов к кластеру
# Запускаем все три узла
systemctl start rabbitmq-server
# На rabbit-2 и rabbit-3:
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster rabbit@rabbit-1
rabbitmqctl start_app
# Проверяем состояние кластера
rabbitmqctl cluster_status
Настройка Quorum Queues
Quorum queues — это правильный выбор для продуктива. Classic mirrored queues устарели и удалены в RabbitMQ 4.0.
# Создание policy для quorum очередей
rabbitmqctl set_policy quorum-queues "^quorum\." \
'{"queue-mode":"quorum"}' \
--priority 1 \
--apply-to queues
# Или создаём очередь с явным типом через Management API
curl -u admin:password -X PUT http://rabbit-1:15672/api/queues/%2F/order-processing \
-H "Content-Type: application/json" \
-d '{
"durable": true,
"arguments": {
"x-queue-type": "quorum",
"x-quorum-initial-group-size": 3,
"x-delivery-limit": 5,
"x-dead-letter-exchange": "dlx",
"x-dead-letter-routing-key": "order-processing.failed"
}
}'
HAProxy для балансировки
# /etc/haproxy/haproxy.cfg
global
log /dev/log local0
maxconn 50000
defaults
mode tcp
log global
retries 3
timeout connect 5s
timeout client 30s
timeout server 30s
frontend rabbitmq-frontend
bind *:5672
default_backend rabbitmq-backend
backend rabbitmq-backend
balance roundrobin
option tcp-check
server rabbit-1 rabbit-1:5672 check inter 5s rise 2 fall 3
server rabbit-2 rabbit-2:5672 check inter 5s rise 2 fall 3
server rabbit-3 rabbit-3:5672 check inter 5s rise 2 fall 3
frontend rabbitmq-mgmt
bind *:15672
default_backend rabbitmq-mgmt-backend
backend rabbitmq-mgmt-backend
balance roundrobin
server rabbit-1 rabbit-1:15672 check
server rabbit-2 rabbit-2:15672 check
server rabbit-3 rabbit-3:15672 check
Настройка пользователей и прав
# Удаляем дефолтного пользователя guest
rabbitmqctl delete_user guest
# Создаём администратора
rabbitmqctl add_user admin $(openssl rand -base64 32)
rabbitmqctl set_user_tags admin administrator
rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
# Приложение — ограниченные права
rabbitmqctl add_user webapp $(openssl rand -base64 32)
rabbitmqctl set_user_tags webapp
# Только нужные exchange и очереди
rabbitmqctl set_permissions -p / webapp \
"^(order|notification|user)\." \
"^(order|notification|user)\." \
"^(order|notification|user)\."
# Мониторинг — только чтение
rabbitmqctl add_user monitoring $(openssl rand -base64 32)
rabbitmqctl set_user_tags monitoring monitoring
Мониторинг
Prometheus exporter встроен в RabbitMQ с версии 3.8:
# Включаем плагины
rabbitmq-plugins enable rabbitmq_prometheus rabbitmq_management
# Метрики доступны на :15692/metrics
Ключевые алерты:
-
rabbitmq_queue_messages{queue="order-processing"} > 10000— очередь растёт -
rabbitmq_node_mem_used / rabbitmq_node_mem_limit > 0.8— memory pressure -
rabbitmq_disk_space_available_bytes < 5368709120— мало места -
rabbitmq_nodes{running="1"} < 3— упал узел кластера
Таймлайн
День 1 — установка Erlang и RabbitMQ на 3 узла, синхронизация Erlang cookie, настройка hostname в /etc/hosts.
День 2 — формирование кластера, создание quorum-очередей, настройка пользователей, policy, dead letter exchange.
День 3 — настройка HAProxy, включение Prometheus exporter, импорт Grafana dashboard (официальный: ID 10991), тестирование отказоустойчивости (выключение одного узла).
День 4 — интеграция с приложением, тест производительности, настройка алертов.







