Введение: почему мониторинг Java-приложений — это база
Современное Java-приложение — это сложная распределённая система. Без мониторинга вы работаете вслепую: падение скорости ответа, утечка памяти или внезапный OutOfMemoryError могут остаться незамеченными до жалобы пользователя. Грамотно настроенный мониторинг метрик и алертов позволяет не только быстро реагировать на инциденты, но и предсказывать узкие места до того, как они станут критическими.
В этой статье мы разберём полный цикл: от сбора базовых метрик JVM до настройки алертов в Prometheus и визуализации в Grafana. Все примеры кода написаны на Java с использованием популярной библиотеки Micrometer.
1. Ключевые метрики Java-приложения
Мониторинг начинается с выбора правильных метрик. Их можно разделить на три группы: метрики JVM, бизнес-метрики и метрики инфраструктуры.
1.1. Метрики JVM
Эти метрики показывают состояние виртуальной машины Java. Самые важные из них:
- Heap memory usage — использование кучи (используемая / максимальная память). Резкий рост может указывать на утечку.
- GC pauses — частота и длительность сборок мусора. Долгие паузы (более 1 секунды) — признак проблем.
- Thread states — количество потоков в состояниях RUNNABLE, BLOCKED, WAITING. Много BLOCKED — возможна блокировка.
- CPU usage — загрузка процессора процессом JVM.
1.2. Бизнес-метрики
Они отражают логику вашего приложения. Примеры:
- Количество обработанных заказов в минуту.
- Время ответа внешнего API.
- Количество ошибок валидации.
1.3. Метрики инфраструктуры
- Использование диска, сети, памяти хоста.
- Состояние подключений к базе данных (пул соединений).
- Задержки очередей сообщений (Kafka, RabbitMQ).
2. Инструменты для сбора метрик: Micrometer + Prometheus
Для Java-приложений стандартом де-факто является библиотека Micrometer. Она предоставляет фасад для различных систем мониторинга (Prometheus, Datadog, Graphite). В связке с Prometheus (хранилище метрик) и Grafana (визуализация) вы получаете мощную и бесплатную экосистему.
2.1. Подключение Micrometer в Spring Boot
Если вы используете Spring Boot 2.x или 3.x, добавьте в pom.xml зависимость:
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
После этого Spring Boot Actuator автоматически включит эндпоинт /actuator/prometheus, который будет отдавать метрики в формате Prometheus.
2.2. Создание кастомной метрики
Допустим, вы хотите считать количество успешных и неуспешных вызовов метода. Создайте счётчик:
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Counter;
import org.springframework.stereotype.Service;
@Service
public class OrderService {
private final Counter successCounter;
private final Counter errorCounter;
public OrderService(MeterRegistry registry) {
this.successCounter = Counter.builder("orders.success")
.description("Number of successful orders")
.register(registry);
this.errorCounter = Counter.builder("orders.error")
.description("Number of failed orders")
.register(registry);
}
public void processOrder(String orderId) {
try {
// логика обработки заказа
successCounter.increment();
} catch (Exception e) {
errorCounter.increment();
throw e;
}
}
}
В Prometheus метрика появится как orders_success_total с меткой по умолчанию.
2.3. Настройка гистограмм для времени ответа
Для измерения времени выполнения используйте Timer:
import io.micrometer.core.instrument.Timer;
import java.util.concurrent.TimeUnit;
public class PaymentService {
private final Timer paymentTimer;
public PaymentService(MeterRegistry registry) {
this.paymentTimer = Timer.builder("payment.execution.time")
.description("Time to process payment")
.publishPercentiles(0.5, 0.95, 0.99)
.register(registry);
}
public void processPayment() {
paymentTimer.record(() -> {
// логика платежа
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
}
Вы получите не только среднее время, но и перцентили (p50, p95, p99), что критически важно для SLA.
3. Настройка алертов: от метрик к уведомлениям
Сами по себе метрики бесполезны, если вы не получаете оповещения при аномалиях. Алерты настраиваются в Prometheus с помощью файла rules.yml.
3.1. Пример правила для высокой загрузки кучи
groups:
- name: java_alerts
rules:
- alert: HighHeapUsage
expr: jvm_memory_used_bytes{area="heap"} / jvm_memory_max_bytes{area="heap"} > 0.85
for: 5m
labels:
severity: warning
annotations:
summary: "Heap usage above 85%"
description: "Heap usage is {{ $value | humanizePercentage }} on instance {{ $labels.instance }}"
Это правило сработает, если использование кучи превысит 85% в течение 5 минут. Алерт можно отправить в Telegram, Slack или PagerDuty через Alertmanager.
3.2. Алерт на частоту ошибок
- alert: HighErrorRate
expr: rate(orders_error_total[5m]) / rate(orders_success_total[5m]) > 0.1
for: 2m
labels:
severity: critical
annotations:
summary: "Error rate > 10%"
description: "Error rate is {{ $value | humanizePercentage }} for the last 5 minutes"
Такой алерт мгновенно сообщит о всплеске ошибок, например, при падении базы данных.
3.3. Health check в Spring Boot
Не забудьте про встроенные health-