Мониторинг 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=} 1

Более подробно про доступные метрики, — в официальной документации.

Сервис 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

Источники данных prometheus

Наконец необходимо настроить отображение интересующих нас метрик в Grafana, и можно приступать непосредственно к мониторингу.

В качестве примера работы метрик, будет рассмотрена следующая ситуация: в новый stream публикуется 2 сообщения, а спустя несколько минут появляется Subscriber читающий данный stream.

Для отправки сообщения используется утилита nats_cli, команда отправки имеет вид:

nats publish <имя jetstream>

Время появление Subscriber на графиках выделено вертикальной линией. График количества Subscribers (метрика gnatsd_connz_total) имеет следующий вид:

Количество Subscriber

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

© Habrahabr.ru