Gymterview
middle

Что такое Prometheus и как он собирает метрики?

Prometheus — open-source система мониторинга и алертинга (CNCF), основанная на модели временных рядов (time series database). Главная особенность — pull-модель: Prometheus сам периодически опрашивает (scrape) endpoints приложений по HTTP.

Пример
┌──────────────┐    GET /actuator/prometheus     ┌──────────────┐
│  Prometheus  │ ─────────────────────────────►  │  Spring Boot │
│   Server     │ ◄─────────────────────────────  │  Application │
│              │    text/plain (metrics)          │              │
└──────────────┘                                  └──────────────┘
     │  scrape каждые 15s
     ▼
┌──────────────┐
│   TSDB       │  Хранение временных рядов
│  (storage)   │
└──────────────┘

Преимущества pull-модели:

  • Prometheus сам контролирует частоту и таймауты
  • Легко обнаружить «упавший» сервис (scrape failed)
  • Не нужно настраивать push-агенты на каждом сервисе
  • Проще отлаживать: можно зайти на endpoint вручную
Конфигурация prometheus.yml
# prometheus.yml
global:
  scrape_interval: 15s
  evaluation_interval: 15s

rule_files:
  - "alert_rules.yml"
  - "recording_rules.yml"

alerting:
  alertmanagers:
    - static_configs:
        - targets: ['alertmanager:9093']

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'order-service'
    metrics_path: '/actuator/prometheus'
    scrape_interval: 10s
    static_configs:
      - targets: ['order-service:8080']
        labels:
          environment: 'production'

  # Service Discovery в Kubernetes
  - job_name: 'kubernetes-pods'
    kubernetes_sd_configs:
      - role: pod
    relabel_configs:
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
        action: keep
        regex: true
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
        action: replace
        target_label: __metrics_path__
        regex: (.+)

Типы метрик в Prometheus

Тип Описание Функции PromQL
counter Монотонно растущее значение rate(), increase(), irate()
gauge Значение, меняющееся в обе стороны avg(), min(), max(), delta()
histogram Распределение значений по бакетам histogram_quantile(), rate() по бакетам
summary Клиентские перцентили (вычисляются на стороне приложения) Прямое чтение перцентилей

PromQL — язык запросов

Пример
# Скорость роста (requests per second) за последние 5 минут
rate(http_server_requests_seconds_count{job="order-service"}[5m])

# Процент ошибок (5xx)
sum(rate(http_server_requests_seconds_count{status=~"5.."}[5m]))
/
sum(rate(http_server_requests_seconds_count[5m]))
* 100

# 99-й перцентиль времени ответа
histogram_quantile(0.99,
  sum(rate(http_server_requests_seconds_bucket{job="order-service"}[5m])) by (le)
)

# Память JVM heap
jvm_memory_used_bytes{area="heap"} / jvm_memory_max_bytes{area="heap"} * 100
Recording Rules и Alerting Rules
# recording_rules.yml
groups:
  - name: http_rules
    interval: 30s
    rules:
      - record: job:http_requests:rate5m
        expr: sum(rate(http_server_requests_seconds_count[5m])) by (job)

      - record: job:http_errors:rate5m
        expr: sum(rate(http_server_requests_seconds_count{status=~"5.."}[5m])) by (job)

      - record: job:http_error_ratio:rate5m
        expr: job:http_errors:rate5m / job:http_requests:rate5m
# alert_rules.yml
groups:
  - name: application_alerts
    rules:
      - alert: HighErrorRate
        expr: job:http_error_ratio:rate5m > 0.05
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "High error rate on {{ $labels.job }}"
          description: "Error rate is {{ $value | humanizePercentage }} for 5 minutes"

      - alert: HighLatency
        expr: histogram_quantile(0.99, sum(rate(http_server_requests_seconds_bucket[5m])) by (le, job)) > 1
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "High p99 latency on {{ $labels.job }}"
          description: "p99 latency is {{ $value }}s"

Важное

  • Prometheus хранит данные локально на диске. Для долгосрочного хранения используйте remote storage (Thanos, Cortex, Grafana Mimir).
  • Pull-модель не подходит для короткоживущих задач (batch jobs). Для них используйте Pushgateway.
  • Лейблы — мощный инструмент, но каждая уникальная комбинация лейблов создаёт отдельный time series. Следите за кардинальностью.
  • Prometheus не гарантирует 100% точность данных: при перезапуске возможны пробелы, scrape может не совпадать с моментом события.

Частые ошибки

  • Не использовать rate() для counter: абсолютное значение counter бесполезно, нужна скорость изменения.
  • Слишком короткий [range] в rate(): rate(...[1m]) при scrape_interval=15s даст всего 4 точки — шумно и неточно. Рекомендуется [5m].
  • Хранить метрики вечно: Prometheus не предназначен для долгосрочного хранения. Настройте retention (по умолчанию 15 дней).
  • Злоупотребление Pushgateway: он предназначен только для batch jobs, не для замены pull-модели.

Как используется в 2026

  • Prometheus 3.x с нативными гистограммами (Native Histograms) и улучшенной производительностью TSDB.
  • Grafana Mimir — горизонтально масштабируемое долгосрочное хранилище, совместимое с Prometheus API.
  • Prometheus Agent Mode — режим, в котором Prometheus только скрейпит и отправляет метрики через remote write, не храня данных локально.
  • Service Discovery — автоматическое обнаружение целей через Kubernetes SD, Consul SD, DNS SD.
  • OpenMetrics — стандартизированный формат метрик (эволюция Prometheus exposition format), поддерживаемый OTel.

На собеседовании: акцентируйте внимание на pull-модели — это главная архитектурная особенность Prometheus. Покажите знание PromQL хотя бы на уровне rate() и histogram_quantile(). Частая ошибка — не упомянуть ограничения (локальное хранение, проблема кардинальности лейблов).