Monitoring Microservices with Prometheus and Grafana
June 8, 2023
Непрерывный мониторинг является критически важным для обеспечения устойчивости систем на основе микросервисов. Без надлежащего мониторинга микросервисы могут быстро перегрузиться, что приведет к ошибкам и снижению производительности.
С помощью непрерывного мониторинга разработчики могут обнаруживать проблемы с их сервисами сразу после их возникновения и принимать меры для предотвращения серьезного ущерба. Он также предоставляет информацию о том, как работают ваши сервисы, позволяя принимать обоснованные решения.
В этой статье будет рассказано, как можно настроить мониторинг для вашего микросервисного приложения с использованием двух популярных инструментов в этой области: Prometheus и Grafana.
Исходный код и файл Docker Compose для этого руководства доступны в репозитории pottekkat/monitoring-101.
Основы Prometheus
Prometheus — это инструмент с открытым исходным кодом для мониторинга и оповещений. Он "забирает" метрики (измерения) из микросервисов, отправляя HTTP-запросы, и сохраняет результаты в базе данных временных рядов.
Вы можете инструментировать свои сервисы, используя клиентские библиотеки, предоставляемые Prometheus. Это позволит вам создавать и собирать пользовательские метрики из ваших сервисов.
Prometheus также имеет экспортеры, которые позволяют забирать метрики, не представленные в формате Prometheus. Экспортер действует как посредник и преобразует экспортированные данные в формат, читаемый Prometheus.

Prometheus предоставляет мощный язык запросов, PromQL, для работы с собранными данными. Вы можете использовать PromQL для создания сложных запросов, чтобы фильтровать, агрегировать и преобразовывать данные в нужный формат.
Помимо сбора метрик, Prometheus также может запускать оповещения, когда установленные пороговые значения превышены. Механизм оповещений является гибко настраиваемым и может отправлять уведомления в такие места, как Slack или электронную почту.
Prometheus имеет графический интерфейс, который позволяет легко визуализировать собранные метрики. Он также интегрируется с другими продвинутыми инструментами визуализации, такими как Grafana.

Типы метрик
Prometheus предлагает четыре основных типа метрик:
- Счетчик (Counter): представляет собой монотонно увеличивающийся счетчик. Его значение может увеличиваться или сбрасываться до нуля при перезапуске. Его можно использовать для представления таких метрик, как количество обработанных запросов.
- Градусник (Gauge): представляет числовое значение, которое может увеличиваться или уменьшаться. Его можно использовать для представления таких значений, как использование памяти или количество запросов в секунду.
- Гистограмма (Histogram): группирует данные в настраиваемые интервалы. Используется для представления таких значений, как длительность запросов или размеры ответов.
- Сводка (Summary): похожа на гистограмму, но также вычисляет настраиваемые значения за скользящее временное окно.
Вы можете узнать больше об этих типах метрик и их использовании из официальной документации.
Пример приложения
Наше примерное приложение будет состоять из API-шлюза, приложения на Go и приложения на Python.

Приложение будет возвращать "Hello <name>!" на выбранном вами языке с указанным именем <name>. Apache APISIX будет выступать в роли API-шлюза, который направляет трафик на ваши сервисы.
На диаграмме ниже показано, как работает система.

- Пользователь отправляет GET-запрос в APISIX, который является точкой входа в приложение.
- APISIX перенаправляет запрос в Go-сервис.
- Go-сервис отправляет GET-запрос в Python-сервис, чтобы получить "Hello" на указанном языке.
- Python-сервис отвечает с требуемым переводом слова "Hello".
- Go-сервис формирует ответ, используя имя, указанное в запросе, и отправляет его в APISIX.
- APISIX перенаправляет ответ обратно пользователю.
Настройка Prometheus для сбора метрик
Мы будем инструментировать и экспортировать метрики из всех сервисов нашего приложения и собирать их в Prometheus. Начнем с нашего API-шлюза, Apache APISIX.
Экспорт метрик из APISIX
Apache APISIX — это облачный API-шлюз с открытым исходным кодом.
Вам не нужно знать об APISIX, чтобы следовать этому руководству, и вы можете использовать предоставленный файл Docker Compose для настройки всего. Чтобы узнать больше об APISIX, посетите api7.ai/apisix.
APISIX предлагает плагин Prometheus, который легко экспортирует метрики в формате Prometheus. Вы можете настроить плагин в конфигурационном файле APISIX:
apisix: enable_admin: false # запуск APISIX в автономном режиме config_center: yaml # использование YAML-файла для конфигурации вместо хранения в etcd plugin_attr: prometheus: export_uri: /prometheus/metrics # включение плагина Prometheus и экспорт метрик на этот URI enable_export_server: false # экспорт метрик на порт по умолчанию для плоскости данных
Теперь мы можем включить плагин на каждом маршруте, сделав его глобальным правилом:
routes: # маршрутизация запросов к /hello/* в go-app - uri: /hello/* upstream: type: roundrobin nodes: "go-app:8080": 1 plugins: # удаление префикса "/hello" перед перенаправлением запроса в go-app proxy-rewrite: regex_uri: - "/hello/(.*)" - "/$1" # экспорт метрик Prometheus на указанный URI - uri: /prometheus/metrics plugins: public-api: # включение плагина Prometheus глобально на всех маршрутах global_rules: - id: 1 plugins: prometheus: prefer_name: true #END
Это экспортирует метрики на конечную точку /prometheus/metrics в Apache APISIX.
Вы можете узнать больше о доступных метриках из документации.
Инструментирование и экспорт метрик из Go-сервиса
Prometheus имеет официальную клиентскую библиотеку для Go для инструментирования приложений на Go.
По умолчанию Prometheus будет экспонировать стандартные метрики Go. Вы также можете создавать свои собственные метрики, специфичные для приложения.
В нашем сервисе мы будем экспонировать стандартные метрики и создадим собственный счетчик для отслеживания количества запросов:
package main import ( "encoding/json" "fmt" "io/ioutil" "log" "net/http" "os" // Пакеты Prometheus "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promhttp" ) // Response хранит сообщение, полученное от python-app type Response struct { Message string `json:"message"` } // язык и имя по умолчанию var ( lang = "en" name = "John" ) // создание нового пользовательского счетчика Prometheus var pingCounter = promauto.NewCounter( prometheus.CounterOpts{ Name: "go_app_request_count", Help: "Количество запросов, обработанных go-app", }, ) // HelloHandler обрабатывает запросы к go-app func HelloHandler(w http.ResponseWriter, r *http.Request) { lang = r.URL.String() name = r.URL.Query()["name"][0] fmt.Println("Запрос для", lang, "с именем", name) pingCounter.Inc() pUrl := os.Getenv("PYTHON_APP_URL") if len(pUrl) == 0 { pUrl = "localhost" } // вызов python-app для получения перевода resp, err := http.Get("http://" + pUrl + ":8000" + lang) if err != nil { log.Fatalln(err) } body, err := ioutil.ReadAll(resp.Body) if err != nil { log.Fatalln(err) } resp.Body.Close() var m Response json.Unmarshal(body, &m) // отправка ответа с "Hello name!" на указанном языке fmt.Fprintf(w, "%s %s!", m.Message, name) } func main() { // экспонирование метрик Prometheus http.Handle("/metrics", promhttp.Handler()) http.HandleFunc("/", HelloHandler) http.ListenAndServe(":8080", nil) }
Это экспонирует метрики на конечную точку /metrics. Вы можете узнать больше о клиентской библиотеке для Go из ее репозитория на GitHub.
Инструментирование и экспорт метрик из Python-сервиса
Prometheus также имеет официальную клиентскую библиотеку для Python. Существуют также сторонние библиотеки, адаптированные для конкретных случаев использования.
Наш сервис использует FastAPI, и мы будем использовать библиотеку prometheus_fastapi_instrumentator для его инструментирования:
from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from prometheus_fastapi_instrumentator import Instrumentator app = FastAPI() hello = {"en": "Hello", "fr": "Bonjour", "es": "Hola", "ml": "ഹലോ"} # экспонирование стандартных метрик Python на конечную точку /metrics Instrumentator().instrument(app).expose(app) @app.get("/{lang}") async def get_hello(lang): return {"message": hello[lang]}
Вы можете узнать больше о создании пользовательских метрик из документации.
Настройка Prometheus
Теперь мы можем собирать и собирать эти метрики в Prometheus.
Вы можете настроить Prometheus для сбора метрик из каждого из сервисов. По умолчанию Prometheus проверяет метрики на пути /metrics:
global: scrape_interval: 15s evaluation_interval: 15s scrape_configs: - job_name: "prometheus" static_configs: - targets: ["localhost:9090"] - job_name: "go-app" static_configs: - targets: ["go-app:8080"] - job_name: "python-app" static_configs: - targets: ["python-app:8000"] - job_name: "apisix" static_configs: - targets: ["apisix:9080"] metrics_path: "/prometheus/metrics"
Вот и все! Теперь, если вы откроете панель управления Prometheus (по умолчанию на порту 9090) и нажмете "Status" в навигационной панели, а затем "Targets", вы сможете увидеть статус сбора метрик из ваших сервисов.

Запросы и визуализация метрик в Prometheus
Теперь вы можете использовать панель управления Prometheus для выполнения запросов и сложных выражений.

Вы можете узнать больше о запросах в Prometheus из официальной документации.
Использование Grafana для запросов к Prometheus
Grafana — это платформа для визуализации данных с открытым исходным кодом, которая работает с Prometheus, предоставляя комплексный инструмент для сбора, запросов и визуализации метрик.
Prometheus хорошо справляется с сбором метрик и запросами, но ему не хватает инструментов для создания значимых визуализаций. Grafana преодолевает это ограничение, преобразуя собранные метрики в визуализации.
Grafana также совместима с многими другими источниками данных, помимо Prometheus.
После развертывания Grafana вы можете открыть веб-интерфейс (по умолчанию на порту 3000).
Сначала вам нужно добавить Prometheus как источник данных. Для этого перейдите в /datasources или "Configuration" и "Data sources". Нажмите "Add data source" и выберите Prometheus. Укажите, где развернут Prometheus, сохраните и проверьте соединение.

Использование предварительно созданных дашбордов Grafana
Grafana предоставляет публичный репозиторий дашбордов, который содержит предварительно созданные дашборды Grafana. Вы можете использовать их в своем экземпляре Grafana для быстрой визуализации соответствующих метрик.
Мы будем использовать дашборд Go Processes, который будет обрабатывать и визуализировать статус процессов, публикуемых клиентской библиотекой Prometheus для Go.
Чтобы импортировать этот шаблон, сначала скопируйте его ID (6671) из репозитория дашбордов. В вашем интерфейсе Grafana перейдите в "Dashboards" и выберите "Import". Вставьте скопированный ID и нажмите "Load".

Вы также можете изучить другие предварительно созданные дашборды или создать свои собственные. Обратитесь к документации, чтобы узнать больше об этом.
Что дальше?
На этом наше руководство завершено!
Эта статья была лишь введением в то, как можно настроить мониторинг для ваших сервисов, и я рекомендую вам узнать больше о Prometheus и Grafana из ресурсов, упомянутых ниже:
Полный код и файл Docker Compose для этого руководства доступны в репозитории pottekkat/monitoring-101.