Мониторинг NATS JetStream в Grafana
Здравствуйте, меня зовут Александр, я backend-разработчик. В данной публикации хочу поделиться опытом настройки мониторинга NATS JetStream. Рассказать для чего в принципе это может понадобиться. А также привести пример необходимого стека сервисов поднятых в docker для мониторинга. В статье не рассматриваются настройки dashboards в Grafana, принципы и особенности работы NATS.
Может возникнуть вопрос для чего же требуется мониторинг, особенно для программного продукта, который в принципе является рабочим. Т.к. мониторинг не является бесплатным — для него требуется настройка и поддержание нескольких сервисов. Однако для оптимизации, добавления новых фич, требуется понимание того, как в реальности используется функционал приложения. И именно метрики могут нам в этом помочь. Метрика — эта численная мера, некоторого свойства или поведения программного обеспечения. В отличии от логов, метрики собирают не все детали, а только готовую выжимку: например, количество запросов к сервису.
Простой пример: есть endpoint который работает, скажем 10 секунд, и на первый взгляд, кажется, что можно попробовать выделить ресурсы для его оптимизации. Но, сбор статистики за месяц показывает, что этим endpoint-ом практически не пользовались. Следовательно, встает закономерный вопрос: стоит ли тратить ресурсы на оптимизацию этого endpoint?
Для начала несколько слов про NATS JetStream. NATS — это система очередей сообщений, которая появилась в 2010, написана на языке Go. NATS хорошо подходит для передачи сообщений в режиме реального времени. На сегодняшний день в NATS JetStream реализована долговечность и гарантированная доставка сообщений.
Для мониторинга NATS будет использоваться следующий стек:
NATS JetStream
Prometheus nats exporter — сервис выступающий неким адаптером между NATS и сервисом Prometheus
Prometheus — отдельный сервис для сбора телеметрии
Grafana — для непосредственного отображения результатов
Для запуска в docker можно использовать следующий docker-compose файл
version: "3.8"
services:
nats:
image: nats:latest
command: --js --debug --trace --sd /data -p 4222 -m 8222
ports:
- 4222:4222
- 6222:6222
- 8222:8222
volumes:
- ./jetstream-cluster/n1:/data
prometheus-nats-exporter:
image: natsio/prometheus-nats-exporter:latest
command: "-connz -varz -channelz -serverz -subz -healthz -routez http://host.docker.internal:8222"
ports:
- "7777:7777"
prometheus:
image: prom/prometheus:latest
hostname: prometheus
volumes:
- "./prometheus.yml:/etc/prometheus/prometheus.yml"
ports:
- "9090:9090"
grafana:
image: grafana/grafana
hostname: grafana
ports:
- "3000:3000"
Немного подробнее о настройках данных сервисов.
В NATS необходимо включить возможность мониторинга на нужном порту. Это можно сделать при помощи параметра -m <номер порта> при запуске сервиса. Более подробно можно прочитать в официальной документации.
NATS поддерживает различные типы метрик. Можно выделить следующие:
varz — общая статистика
connz — статистика соединений
routez — информация о маршрутах
subsz — информация о подписчиках
jsz — информация о стримах (jetstreams)
Результаты, отображаемые в данных метриках, можно посмотреть в сервисе NATS по пути : http://localhost:8222/<название метрики>, к примеру http://localhost:8222/varz
Далее в конфигурационном файле NATS Prometheus exporter необходимо указать источник данных, т.е. сервис NATS (порт, который указан в параметре -m), а также указать какие именно метрики нужно собирать. Это выполняется при помощи команды
prometheus-nats-exporter -varz "http://localhost:5555
где через дефис указываются необходимые метрики.
Итоговый результат полученных метрик из Prometheus nats exporter можно увидеть по пути http://localhost:7777/metrics. Этот путь можно переопределить при помощи параметра -path.
Метрики имеют следующий вид: вначале идет ее описание и тип, а затем сама метрика и ее значение в формате <Название метрики>{label} <значение>.
Содержимое label можно использовать в Grafana для группировки/ сортировки или отображения результатов. К примеру, метрика «Потребление ресурсов процессора (CPU, %)»
gnatsd_varz_cpu{server_id=
Более подробно про доступные метрики, — в официальной документации.
Сервис Prometheus занимается сбором телеметрии, в нем имеется список источников данных, и он периодически опрашивает их. Для запуска Prometheus можно использовать файл prometheus.yml
В блоке targets: ['host.docker.internal:7777']) указывается источник данных (хост и порт) в качестве которого, в данном случае, выступает prometheus nats exporter. При этом при запуске в docker нельзя указывать localhost. Т.к. внутри среды docker у prometheus nats exporter нет доступа к открытым портам хост-машины. Нужно использовать либо http://host.docker.internal, либо адрес с именем контейнера. Дополнительно, про настройку prometheus можно прочитать в статье.
Далее можно проверить доступность источника данных prometheus nats exporter. Все доступные источники данных для prometheus отображаются по адресу http://localhost:9090/targets
Источники данных prometheus
Наконец необходимо настроить отображение интересующих нас метрик в Grafana, и можно приступать непосредственно к мониторингу.
В качестве примера работы метрик, будет рассмотрена следующая ситуация: в новый stream публикуется 2 сообщения, а спустя несколько минут появляется Subscriber читающий данный stream.
Для отправки сообщения используется утилита nats_cli, команда отправки имеет вид:
nats publish <имя jetstream>
Время появление Subscriber на графиках выделено вертикальной линией. График количества Subscribers (метрика gnatsd_connz_total) имеет следующий вид:
Количество Subscriber
На графике необработанных сообщений (метрика jetstream_consumer_num_pending) видно, что при появлении Subscriber, число необработанных сообщений становиться ноль.
Число необработанных сообщений
При этом на графике общего количества сообщений (метрика jetstream_server_total_messages) изменений не происходит.
Общее число сообщений
Можно выделить следующие важные метрики NATS.
gnatsd_varz_cpu — Потребление ресурсов процессора (CPU, %)
gnatsd_varz_mem — Потребление оперативной памяти
gnatsd_connz_total — Число Subscribers
jetstream_server_total_messages — Всего сообщений в jetstream
jetstream_server_total_message_bytes — Размер всех сообщений в jetstream
jetstream_consumer_num_pending — Ожидающие сообщений в jetstream
gnatsd_varz_in_msgs — Входящие сообщения от Publisher в NATS
gnatsd_varz_out_msgs — Ответы на сообщения от Subscriber в NATS
Все эти метрики можно вынести на отдельный экран, что позволит быстро анализировать актуальное состояние всего сервиса NATS JetStream.
В NATS доступен широкий спектр различных метрик. Необходимые метрики должны быть выбраны исходя из конкретной ситуации и в зависимости от цели мониторинга.