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

Что такое Prometheus?

1.7 Middle🔥 251 комментариев
#Docker, Kubernetes и DevOps

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

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

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

Что такое Prometheus?

Prometheus — это открытая система мониторинга и оповещения (monitoring and alerting system), которая собирает метрики из приложений и инфраструктуры, хранит их временных рядов и предоставляет мощный язык запросов для анализа. За 10+ лет я использую Prometheus во всех production приложениях, и это стало стандартом для наблюдаемости в облачных системах.

История Prometheus

Prometheus был создан компанией SoundCloud в 2012 году для мониторинга своей инфраструктуры. В 2016 году он был передан Cloud Native Computing Foundation (CNCF), и сейчас это segundo по популярности проект в CNCF после Kubernetes.

Что такое Prometheus простыми словами

Prometheus — это система, которая:

  1. Собирает метрики (metrics) из приложений через HTTP
  2. Хранит их в базе данных временных рядов (time-series database)
  3. Анализирует через язык запросов PromQL
  4. Визуализирует через Grafana или встроенный dashboard
  5. Запускает алерты когда метрики превышают пороги
┌─────────────────────┐
│  Java Приложение    │ (app:8080/metrics)
│  + Spring Actuator  │
└──────────┬──────────┘
           │
           │ HTTP pull каждые 15 сек
           ▼
┌─────────────────────┐
│    Prometheus       │ (localhost:9090)
│  (Pull модель)      │
└──────────┬──────────┘
           │
      ┌────┴────┐
      ▼         ▼
  ┌───────┐ ┌───────────┐
  │Grafana│ │AlertManager│
  └───────┘ └───────────┘

Ключевые концепции

1. Metrics (Метрики)

Метрика — это число, которое изменяется во времени. Каждая метрика имеет имя и лейблы:

http_requests_total{method="GET", status="200"} 1234
jvm_memory_used_bytes{area="heap"} 512000000
process_cpu_seconds_total 123.45

Типы метрик:

import io.micrometer.prometheus.PrometheusMeterRegistry;
import io.micrometer.core.instrument.*;

@Configuration
public class PrometheusConfig {
    @Bean
    public PrometheusMeterRegistry registry() {
        return new PrometheusMeterRegistry();
    }
}

@Service
public class MetricsService {
    private final MeterRegistry meterRegistry;
    
    public MetricsService(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
    }
    
    // 1. Counter - только растет
    public void trackApiCall() {
        Counter.builder("api.calls.total")
            .tag("endpoint", "/users")
            .tag("method", "GET")
            .register(meterRegistry)
            .increment();
    }
    
    // 2. Gauge - может расти и падать
    public void trackQueueSize() {
        Gauge.builder("queue.size", () -> getQueueSize())
            .register(meterRegistry);
    }
    
    // 3. Histogram - распределение значений
    public void trackResponseTime() {
        Timer.builder("http.request.duration")
            .publishPercentiles(0.5, 0.95, 0.99)
            .register(meterRegistry)
            .record(() -> {
                // Выполнить операцию
            });
    }
    
    // 4. Summary - похож на Histogram
    public void trackProcessingTime() {
        Timer timer = Timer.builder("task.duration")
            .register(meterRegistry);
        timer.record(() -> {
            // Выполнить задачу
        });
    }
}

2. Pull vs Push модель

Prometheus использует Pull модель (в отличие от других систем):

// Приложение отвечает на /metrics с метриками
@RestController
public class MetricsEndpoint {
    @GetMapping("/metrics")
    public String getMetrics() {
        // Prometheus периодически запрашивает этот endpoint
        return "# HELP jvm_memory_used_bytes Java heap memory used\n" +
               "# TYPE jvm_memory_used_bytes gauge\n" +
               "jvm_memory_used_bytes{area=\"heap\"} 512000000";
    }
}

// Prometheus конфиг (prometheus.yml)
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'java-app'
    static_configs:
      - targets: ['localhost:8080']
    metrics_path: '/actuator/prometheus'

3. PromQL - язык запросов

PromQL (Prometheus Query Language) позволяет анализировать метрики:

# Получить значение метрики
jvm_memory_used_bytes{area="heap"}

# Скорость изменения (в минуту)
rate(http_requests_total[5m])

# Сумма по лейблам
sum(http_requests_total) by (status)

# Процент успешных запросов
100 * sum(rate(http_requests_total{status="200"}[5m])) / 
      sum(rate(http_requests_total[5m]))

# Предсказание на 1 час вперед
predict_linear(node_filesystem_free[1h], 3600)

Spring Boot интеграция

// pom.xml
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

// application.yml
spring:
  application:
    name: java-app

management:
  endpoints:
    web:
      exposure:
        include: metrics,prometheus
  metrics:
    export:
      prometheus:
        enabled: true

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

// Метрики доступны на http://localhost:8080/actuator/prometheus

Docker Compose пример

version: '3'
services:
  # Java приложение
  app:
    image: my-java-app:latest
    ports:
      - "8080:8080"
    environment:
      - JAVA_OPTS=-Xmx512m

  # Prometheus
  prometheus:
    image: prom/prometheus:latest
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'

  # Grafana для визуализации
  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    depends_on:
      - prometheus

Настройка алертов

# prometheus.yml
alertmanager_config:
  - static_configs:
      - targets:
          - alertmanager:9093

rule_files:
  - "alerts.yml"

# alerts.yml
groups:
  - name: java_alerts
    interval: 30s
    rules:
      # Алерт если хип близок к максимуму
      - alert: HighMemoryUsage
        expr: (jvm_memory_used_bytes{area="heap"} / jvm_memory_max_bytes{area="heap"}) > 0.9
        for: 5m
        annotations:
          summary: "High memory usage detected"

      # Алерт если много ошибок
      - alert: HighErrorRate
        expr: rate(http_requests_total{status="5xx"}[5m]) > 0.01
        for: 2m
        annotations:
          summary: "Error rate above 1%"

      # Алерт если приложение не отвечает
      - alert: AppDown
        expr: up{job="java-app"} == 0
        for: 1m
        annotations:
          summary: "Application is down"

Лучшие практики

@Service
public class OrderService {
    private final MeterRegistry meterRegistry;
    private final Timer orderProcessingTimer;
    private final Counter successfulOrders;
    private final Counter failedOrders;
    
    public OrderService(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
        
        // Регистрируем метрики один раз
        this.orderProcessingTimer = Timer.builder("order.processing.time")
            .publishPercentiles(0.5, 0.95, 0.99)
            .minimumExpectedValue(Duration.ofMillis(10))
            .maximumExpectedValue(Duration.ofSeconds(5))
            .register(meterRegistry);
        
        this.successfulOrders = Counter.builder("orders.processed.success")
            .register(meterRegistry);
        
        this.failedOrders = Counter.builder("orders.processed.failed")
            .register(meterRegistry);
    }
    
    public void processOrder(Order order) {
        // Измеряем время обработки
        orderProcessingTimer.record(() -> {
            try {
                // Логика обработки
                doProcess(order);
                successfulOrders.increment();
            } catch (Exception e) {
                failedOrders.increment();
                throw e;
            }
        });
    }
    
    // Кастомные метрики
    public void trackInventory() {
        Gauge.builder("inventory.items", () -> getInventoryCount())
            .tag("warehouse", "us-east")
            .register(meterRegistry);
    }
}

Что мониторить

# JVM метрики
jvm_memory_used_bytes
jvm_threads_live
jvm_gc_pause_seconds

# Приложение
http_requests_total
http_request_duration_seconds
db_query_duration_seconds

# Система
process_cpu_seconds_total
process_resident_memory_bytes
disk_read_bytes_total

Заключение

Prometheus — это стандарт для мониторинга в облачных приложениях. Он:

  • Полнотекстовый — включает собирание, хранение и анализ
  • Гибкий — поддерживает любые метрики
  • Мощный — язык PromQL позволяет писать сложные запросы
  • Масштабируемый — используется в production приложениях с миллионами метрик
  • Open source — бесплатный и с хорошей поддержкой

Владение Prometheus критично для любого Java разработчика, работающего с облачными приложениями и микросервисами.