← Назад к вопросам

Расскажи про опыт работы с Prometheus

2.3 Middle🔥 211 комментариев
#Observability

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

🐱
step-3.5-flashPrepBro AI4 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Опыт работы с Prometheus в контексте Go-разработки

Prometheus стал неотъемлемой частью стека мониторинга в моих проектах на протяжении последних 7 лет. Как Go Developer, я активно интегрирую его на этапе проектирования и разработки сервисов, превращая метрики из второстепенного элемента в критически важный компонент для обслуживания и диагностики.

Основные направления опыта:

1. Интеграция Prometheus Client Library в Go-сервисы

Я использую официальную библиотеку github.com/prometheus/client_golang как основу для экспозиции метрик. Ключевые практики:

  • Автоматическая регистрация метрик через MustRegister в init()-функциях для гарантии инициализации.
  • Использование кастомных метрик (Counters, Gauges, Histograms, Summaries) для отслеживания бизнес-логики, а не только системных показателей.
  • Экспозиция метрик через HTTP эндпоинт (/metrics) с минимальным воздействием на производительность.

Пример кода для создания кастомных метрик:

import (
    "net/http"
    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/promauto"
    "github.com/prometheus/client_golang/prometheus/promhttp"
)

var (
    requestsTotal = promauto.NewCounterVec(
        prometheus.CounterOpts{
            Name: "http_requests_total",
            Help: "Общее количество HTTP запросов,拆分 by method and path",
        },
        []string{"method", "path", "status_code"},
    )
    requestDuration = promauto.NewHistogramVec(
        prometheus.HistogramOpts{
            Name:    "http_request_duration_seconds",
            Help:    "Длительность HTTP запросов в секундах",
            Buckets: prometheus.DefBuckets,
        },
        []string{"method", "path"},
    )
)

func init() {
    // Регистрация метрик в глобальном реестре
    prometheus.MustRegister(requestsTotal, requestDuration)
}

func MetricsHandler() http.Handler {
    return promhttp.Handler()
}

2. Работа с метками (Labels) и управление кардинальностью

ЯTill偿 провёл несколько инцидентов из-за высокой кардинальности меток, что привело к взрывному росту потребления памяти в Prometheus. Мои правила:

  • Ограничение уникальных значений меток (например, избегание user_id или request_id в качестве меток).
  • Использование статичных меток (static labels) для идентификации сервиса, окружения, региона.
  • Регулярный аудит метрик через label_values() и label_join() в запросах.

Пример плохой и хорошей практики:

// ПЛОХО: высокая кардинальность из-за request_id
requestsTotal.WithLabelValues("GET", "/api/users", "12345-abcde").Inc()

// ХОРОШО: ограничиваемся стабильными метками
requestsTotal.WithLabelValues("GET", "/api/users", "200").Inc()

3. Настройка экспортеров и сбор системных метрик

Помимо прикладных метрик, я работал с:

  • Node Exporter для сбора аппаратных и ОС-метрик (CPU, memory, disk, network).
  • Blackbox Exporter для проверки доступности эндпоинтов (HTTP, TCP, ICMP).
  • Custom Exporters на Go для внутренних систем (например, сбор метрик из RabbitMQ, Redis).

Пример конфигурации scrape_configs для Go-сервиса:

scrape_configs:
  - job_name: 'go-services'
    static_configs:
      - targets: ['service1:8080', 'service2:8080']
    metrics_path: '/metrics'
    params:
      'format': ['prometheus']
    relabel_configs:
      - source_labels: [__address__]
        target_label: instance
      - source_labels: [__meta_kubernetes_pod_name]
        target_label: pod

4. Оптимизация производительности

  • Минимальное воздействие на код: метрики инкрементируются в конце обработки запроса, а не в начале.
  • Использование promhttp.InstrumentMetricHandler для автоматического сбора метрик HTTP-сервера.
  • Буферизация для Counter и Gauge при высокой нагрузке (через promauto.NewCounterVec).

5. Работа с Alertmanager и Grafana

  • Настройка правил алертов в Prometheus на основе кастомных метрик (например, высокий процент ошибок, рост времени ответа).
  • Создание dashboard'ов в Grafana с использованием pre-built dashboard'ов (например, для Go-приложений — "Go processes").
  • SLO/SLI-мониторинг: расчет error budget на основе метрик (rate(http_requests_total{status=~"5.."}[5m])).

6. Мониторинг в микросервисной архитектуре

  • Единый формат метрик для всех сервисов (стандартизация имен, единицы измерения).
  • Distributed tracing корреляция через propagation trace ID в метках (например, trace_id для связи логов, трейсов и метрик).
  • Мульти-тенантность через метку tenant_id для SaaS-приложений.

Проблемы и решения:

  • Memory leak из-за high cardinality: решение — добавление relabel_configs для отсеивания ненужных меток.
  • Задержка в сборе метрик: настройка scrape_interval в зависимости от критичности (15s для бизнес-метрик, 60s для системных).
  • Безопасность эндпоинта /metrics: использование сети, отдельного порта, или аутентификации через reverse proxy (nginx, Traefik).

Заключение:

Prometheus для меня — это не просто система мониторинга, а инструмент обратной связи для разработки. Я внедряю метрики-first подход: перед написанием кода определяю, какие метрики будут нужны для оценки работы функции. Это позволяет создавать более отказоустойчивые и наблюдаемые системы. В коммерческих проектах я достиг снижения MTTR на 40% за счет быстрой диаганостики через метрики и алерты.