Брокер сообщений 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 для приложений и сокращает время от начала разработки до выхода продукта на рынок.

Делитесь в комментариях какими брокерами сообщений вы пользуетесь и какие темы в разработке вам интересны.

Читайте также:

Комментарии (2)


  1. lioncub
    22.01.2025 08:47

    Что ж вы политики в интерфейс не добавили?


    1. dbraincloud Автор
      22.01.2025 08:47

      Добрый день! Мы предоставили наиболее релевантные для нас скриншоты, к сожалению, не имеем возможности показать все нюансы.