Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое Prometheus?
Prometheus — это открытая система мониторинга и оповещения (monitoring and alerting system), которая собирает метрики из приложений и инфраструктуры, хранит их временных рядов и предоставляет мощный язык запросов для анализа. За 10+ лет я использую Prometheus во всех production приложениях, и это стало стандартом для наблюдаемости в облачных системах.
История Prometheus
Prometheus был создан компанией SoundCloud в 2012 году для мониторинга своей инфраструктуры. В 2016 году он был передан Cloud Native Computing Foundation (CNCF), и сейчас это segundo по популярности проект в CNCF после Kubernetes.
Что такое Prometheus простыми словами
Prometheus — это система, которая:
- Собирает метрики (metrics) из приложений через HTTP
- Хранит их в базе данных временных рядов (time-series database)
- Анализирует через язык запросов PromQL
- Визуализирует через Grafana или встроенный dashboard
- Запускает алерты когда метрики превышают пороги
┌─────────────────────┐
│ 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 разработчика, работающего с облачными приложениями и микросервисами.