Внедрение RabbitMQ в облачную платформу: проблемы и решения

от автора

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

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

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


ссылка на оригинал статьи https://habr.com/ru/articles/875366/