junior
Что такое метрики и какие типы метрик существуют?
Метрика — числовое значение, измеряемое в определённый момент времени, которое агрегируется и хранится как временной ряд (time series). Каждый временной ряд идентифицируется именем и набором лейблов (меток).
Пример
http_server_requests_seconds_count{method="GET", uri="/api/orders", status="200"} 1523
│ │ │
│ имя метрики │ лейблы (dimensions) │ значение
Основные типы метрик
| Тип | Описание | Примеры | Функции PromQL |
|---|---|---|---|
| Counter | Монотонно возрастающее значение (сбрасывается в 0 при перезапуске) | Количество HTTP-запросов, число ошибок | rate(), increase() |
| Gauge | Значение, которое может увеличиваться и уменьшаться | Активные подключения, размер очереди, heap usage | avg(), min(), max() |
| Histogram | Распределение значений по бакетам | Время ответа, размер запроса | histogram_quantile() |
| Timer | Counter + Histogram для измерения длительности | Время обработки заказа | rate(), histogram_quantile() |
Примеры кода для каждого типа
// Counter
Counter orderCounter = Counter.builder("orders.created")
.description("Total number of created orders")
.tag("region", "eu")
.register(meterRegistry);
orderCounter.increment();
// Gauge
Gauge.builder("queue.size", queue, Queue::size)
.description("Current queue size")
.register(meterRegistry);
// Histogram (DistributionSummary)
DistributionSummary summary = DistributionSummary.builder("order.amount")
.description("Order amounts distribution")
.baseUnit("rubles")
.publishPercentiles(0.5, 0.95, 0.99)
.publishPercentileHistogram()
.register(meterRegistry);
summary.record(orderAmount);
// Timer
Timer timer = Timer.builder("order.processing.time")
.description("Time to process an order")
.publishPercentiles(0.5, 0.95, 0.99)
.register(meterRegistry);
timer.record(() -> processOrder(order));
Методологии выбора метрик
RED-метод — для сервисов (запрос-ответ):
- Rate — количество запросов в секунду
- Errors — количество неудачных запросов в секунду
- Duration — распределение времени ответа (гистограмма)
USE-метод — для ресурсов (CPU, память, диск, сеть):
- Utilization — процент использования ресурса
- Saturation — степень перегрузки (очередь ожидания)
- Errors — количество ошибок ресурса
Бизнес-метрики vs Технические метрики
| Бизнес-метрики | Технические метрики |
|---|---|
| Количество заказов в минуту | CPU utilization |
| Конверсия корзины | JVM heap usage |
| Среднее время доставки | HTTP response time |
| Выручка в реальном времени | Connection pool utilization |
| Количество активных пользователей | GC pause duration |
Пример бизнес-метрики
@Service
public class PaymentService {
private final Counter successPayments;
private final Counter failedPayments;
private final DistributionSummary paymentAmount;
public PaymentService(MeterRegistry registry) {
this.successPayments = Counter.builder("payments.success")
.tag("provider", "stripe")
.register(registry);
this.failedPayments = Counter.builder("payments.failed")
.tag("provider", "stripe")
.register(registry);
this.paymentAmount = DistributionSummary.builder("payments.amount")
.baseUnit("kopecks")
.publishPercentiles(0.5, 0.95)
.register(registry);
}
public PaymentResult pay(PaymentRequest request) {
try {
PaymentResult result = processPayment(request);
successPayments.increment();
paymentAmount.record(request.getAmount());
return result;
} catch (PaymentException e) {
failedPayments.increment();
throw e;
}
}
}
Важное
- Counter нельзя использовать для значений, которые уменьшаются (например, количество активных сессий — это Gauge).
- При работе с Counter в Prometheus всегда используйте функцию
rate()илиincrease(), а не абсолютное значение. - Перцентили нельзя агрегировать между инстансами: p99 от 5 инстансов — это не p99 системы. Для агрегации используйте гистограммы.
- Лейблы с высокой кардинальностью (userId, requestId) убивают производительность Prometheus. Используйте лейблы с ограниченным набором значений.
Частые ошибки
- Использование Gauge вместо Counter для подсчёта событий: при перезапуске теряется контекст, а
rate()не работает корректно. - Высокая кардинальность лейблов: добавление
userIdилиorderIdкак лейбла создаёт миллионы time series и перегружает хранилище. - Отсутствие бизнес-метрик: техническая команда мониторит только инфраструктуру, но не понимает, влияет ли деградация на бизнес.
- Неправильный выбор бакетов гистограммы: дефолтные бакеты могут не подходить для конкретного SLA. Настраивайте
serviceLevelObjectives().
Как используется в 2026
- Micrometer 1.13+/2.x — стандарт для метрик в Spring-экосистеме, с нативной поддержкой OpenTelemetry.
- Exemplars — связь метрик с трейсами. Prometheus поддерживает exemplars, позволяя «кликнуть» на spike в графике и перейти к конкретному трейсу.
- Prometheus Native Histograms — новый формат гистограмм с автоматическим выбором бакетов и экономией места.
- PromQL остаётся основным языком запросов; Grafana поддерживает визуальный query builder.
На собеседовании: важно не просто перечислить Counter/Gauge/Histogram, а объяснить, когда какой тип применять. Покажите знание RED/USE-методологий и упомяните, что бизнес-метрики часто важнее технических. Классическая ловушка — забыть про ограничение кардинальности лейблов.