Брокер сообщений RabbitMQ используется в современных архитектурах микросервисов и распределенных системах. Это сервис, который полезен для высоконагруженных проектов в области банковской деятельности, телекома, социальных сетей и др. То есть там, где циркулируют миллионы сообщений. Использование брокера для управления очередями сообщений позволяет эффективно обрабатывать данные и оптимизирует нагрузку между компонентами приложений. Внедрение RabbitMQ в платформу контейнеризации dBrain.cloud стало важным шагом к оптимизации процессов обмена сообщениями и управления данными.

В этой статье мы рассмотрим, как RabbitMQ интегрирован в dBrain, какие операторы использованы для управления кластерами, а также с какими проблемами столкнулись разработчики в процессе внедрения. Обсудим ключевые настройки и рекомендации по оптимизации работы RabbitMQ, что позволит лучше понять его возможности и преимущества в контексте контейнеризации.
Что такое брокер RabbitMQ
RabbitMQ - один из самых популярных брокеров сообщений наряду с Kafka. Kafka построена по принципу “глупый брокер, умный потребитель”, RabbitMQ - “умный брокер, глупый потребитель”. В RabbitMQ можно строить логику обработки и направления сообщений, в то время как Kafka - это просто лог данных, а вся логика хранится в консьюмерах. Kafka обычно используется с большим потоком сообщений или данных, например, десятки или сотни тысяч сообщений в секунду. Если в приложении не планируется обрабатывать такие объемы, то стоит рассмотреть RabbitMQ: он более легковесный в потреблении ресурсов и проще в настройке. У каждого брокера есть плюсы и минусы, оба используют в крупных компаниях.
В dBrain мы используем оба брокера, чтобы закрывать потребности компаний любого размера и запросов к функционалу MQ (Message queue).
Как реализовали в dBrain
В платформе dBrain предусмотрен инструмент для создания и развертывания приложений, управления базами данных и мониторинга - консоль. Это веб-интерфейс, который упрощает взаимодействие с инфраструктурой, базами данных, Kubernetes. Из консоли dBrain в пару кликов можно развернуть любой сервис (как это происходит, можно прочитать тут). Брокер RabbitMQ также можно развернуть с помощью интерфейса dBrain.

В dBrain мы реализовали управление RabbitMQ на основе двух популярных операторов:
Первый управляет непосредственно кластерами RabbitMQ, второй - всеми остальными элементами в кластере, такими как User, Vhost, Queue, Exchange, Binding и тд.
Проблемы внедрения
При внедрении брокера в платформу контейнеризации dBrain возникли некоторые нюансы. Например, проблема с дефолтными настройками RabbitMQ Cluster: сервис не утилизировал (не использовал по максимуму) всю выделенную RAM (random-access memory).
Для этого мы обратились к настройке vm_memory_high_watermark, она по дефолту равна 40%. На первом шаге попробовали заменить настройку на vm_memory_high_watermark.relative = 0.7 (согласно рекомендациям). Это улучшило утилизацию, но привело к периодическому рестарту подов. После более детального изучения документации мы изменили настройку как рекомендовано тут и тут, немного скорректировав логику расчета: vm_memory_high_watermark.absolute = {{ (memory * 0.7) | int }}Mi.Операция приведения к int обязательна, т.к. RabbitMQ не запустится, если указать не целое число.
Для продакшен-окружения рекомендуем установить настройку disk_free_limit.relative = 1.0 чтобы RabbitMQ мог сбросить все содержимое из памяти на диск. Также стоит выбрать настройку cluster_partition_handling. Если у вас нечетное количество инстансов, рекомендуем выставить в pause_minority.

Настройка RabbitMQ включает несколько уровней:
rabbitmq.conf - основной файл настроек, самый удобный и простой:
advanced.config - конфиг в формате Erlang-а: ограниченный набор настроек, используется, когда не подошел пункт 1
rabbitmq-env.conf - файл для настроек переменных окружения
Дополнительный функционал в RabbitMQ подключается через набор плагинов. Список предустановленных плагинов можно проверить, выполнив в поде команду rabbitmq-plugins list. Там же можно увидеть список включенных плагинов. Мы дополнительно включили плагин rabbitmq_top, который предоставляет простой, но информативный UI. Он нужен, когда необходимо посмотреть детальную информацию.
Самый простой способ включения настроек для мониторинга в RabbitMQ реализован аналогично - через плагин rabbitmq_prometheus. Он открывает порт и предоставляет метрики в формате prometheus. Далее по набору лейблов на поде RabbitMQ через указанный для мониторинга порт VictoriaMetrics забирает метрики согласно описанию ниже.
apiVersion: operator.victoriametrics.com/v1beta1 kind: VMPodScrape metadata: name: rabbitmq-metrics namespace: mon labels: component: rabbitmq spec: podTargetLabels: - "cluster-name" namespaceSelector: any: true selector: matchLabels: component: rabbitmq app.kubernetes.io/part-of: rabbitmq database-metrics-enabled: true podMetricsEndpoints: - port: prometheus path: /metrics
Подобный пример из оператора тут (как и пример алертов для RabbitMQ).
Помимо самого кластера RabbitMQ в dBrain можно управлять внутренними элементами кластера, такими как Vhost, User, Queue, Binding, Exchange.
Для примера создадим в кластере эти сущности (все настройки можно найти тут):
apiVersion: rabbitmq.com/v1beta1 kind: Vhost metadata: name: rabbitmq-cluster1-vhost-host1 namespace: backend labels: app: rabbitmq-cluster1 component: rabbitmq cluster-name: cluster1 spec: name: host1 tracing: false defaultQueueType: classic rabbitmqClusterReference: name: rabbitmq-cluster1 namespace: backend
apiVersion: rabbitmq.com/v1beta1 kind: Queue metadata: name: rabbitmq-cluster1-queue-queue1 namespace: backend labels: app: rabbitmq-cluster1 component: rabbitmq cluster-name: cluster1 spec: name: queue1 vhost: host1 type: classic autoDelete: false durable: true rabbitmqClusterReference: name: rabbitmq-cluster1 namespace: backend
apiVersion: rabbitmq.com/v1beta1 kind: Exchange metadata: name: rabbitmq-cluster1-exchange-exchange1 namespace: backend labels: app: rabbitmq-cluster1 component: rabbitmq cluster-name: cluster1 spec: name: exchange1 vhost: host1 type: direct autoDelete: false durable: true rabbitmqClusterReference: name: rabbitmq-cluster1 namespace: backend
apiVersion: rabbitmq.com/v1beta1 kind: Binding metadata: name: rabbitmq-cluster1-binding-queue1-to-exchange1-xyz namespace: backend labels: app: rabbitmq-cluster1 component: rabbitmq cluster-name: cluster1 spec: vhost: host1 source: queue1 destination: exchange1 destinationType: exchange routingKey: "product.*" rabbitmqClusterReference: name: rabbitmq-cluster1 namespace: backend
Создадим юзера, креды и права в кластере:

apiVersion: v1 kind: Secret metadata: name: rabbitmq-cluster1-user1 namespace: backend labels: app: rabbitmq-cluster1 component: rabbitmq cluster-name: cluster1 type: Opaque stringData: username: user1 password: secret_password
apiVersion: rabbitmq.com/v1beta1 kind: User metadata: name: rabbitmq-cluster1-user1 namespace: backend labels: app: rabbitmq-cluster1 component: rabbitmq cluster-name: cluster1 spec: rabbitmqClusterReference: name: rabbitmq-cluster1 namespace: backend importCredentialsSecret: name: rabbitmq-cluster1-user1
apiVersion: rabbitmq.com/v1beta1 kind: Permission metadata: name: rabbitmq-cluster1-user1-permission-yxz namespace: backend labels: app: rabbitmq-cluster1 component: rabbitmq cluster-name: cluster1 spec: vhost: host1 user: user1 permissions: write: "*" configure: "*" read: "*" rabbitmqClusterReference: name: rabbitmq-cluster1 namespace: backend

Если в будущем потребуется изменить пароль пользователя, то просто поменять значения в Secret для этого юзера будет недостаточно. Существует важный нюанс: оператор не отслеживает изменения в Secret'ах. Чтобы оператор смог увидеть новое значение и обновить пароль в RabbitMQ, необходимо модифицировать содержимое лейблов или аннотаций в User.
Вывод
Внедрение RabbitMQ в dBrain - это развитие функционала платформы в соответствии запросами клиентов, которые хотят видеть альтернативу Kafka. Основные функции управления RabbitMQ доступны через пользовательский интерфейс dBrain. В редких случаях, когда требуются специфические изменения, можно воспользоваться YAML-конфигурациями. Добавление сервиса в dBrain упрощает запуск и управление RabbitMQ для приложений и сокращает время от начала разработки до выхода продукта на рынок.
Делитесь в комментариях какими брокерами сообщений вы пользуетесь и какие темы в разработке вам интересны.
Читайте также:
