Что такое Micrometer и как его использовать в Spring Boot?
Micrometer — библиотека-фасад для сбора метрик в JVM-приложениях. По аналогии с SLF4J для логирования, Micrometer предоставляет единый API для работы с метриками, а конкретная реализация (backend) подключается отдельно.
Аналогия из жизни: Micrometer — это как универсальная розетка-переходник. Вы подключаете прибор (приложение) через один стандартный разъём, а на выходе можете подключить любую сеть — Prometheus, Datadog, CloudWatch.
Поддерживаемые бэкенды
Prometheus, Datadog, New Relic, CloudWatch, InfluxDB, Graphite, StatsD, Dynatrace, Elastic, Wavefront, OpenTelemetry.
Подключение к Spring Boot
Пример
<!-- pom.xml -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Для экспорта в Prometheus -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
Пример
# application.yml
management:
endpoints:
web:
exposure:
include: health, info, metrics, prometheus
metrics:
tags:
application: ${spring.application.name}
distribution:
percentiles-histogram:
http.server.requests: true
sla:
http.server.requests: 100ms, 500ms, 1s
MeterRegistry — центральный компонент
MeterRegistry — интерфейс, через который регистрируются все метрики. Spring Boot автоматически создаёт и настраивает нужную реализацию.
Пример OrderMetrics с Counter, Timer, Gauge
@Component
public class OrderMetrics {
private final Counter createdOrders;
private final Timer orderProcessingTimer;
private final AtomicInteger pendingOrders = new AtomicInteger(0);
public OrderMetrics(MeterRegistry registry) {
this.createdOrders = Counter.builder("orders.created.total")
.description("Total number of created orders")
.register(registry);
this.orderProcessingTimer = Timer.builder("orders.processing.duration")
.description("Order processing duration")
.publishPercentiles(0.5, 0.95, 0.99)
.publishPercentileHistogram()
.register(registry);
Gauge.builder("orders.pending", pendingOrders, AtomicInteger::get)
.description("Number of pending orders")
.register(registry);
}
public void onOrderCreated() {
createdOrders.increment();
pendingOrders.incrementAndGet();
}
public void onOrderProcessed() {
pendingOrders.decrementAndGet();
}
public Timer getProcessingTimer() {
return orderProcessingTimer;
}
}
Аннотация @Timed
Пример
@RestController
@RequestMapping("/api/orders")
public class OrderController {
@Timed(value = "orders.get.time",
description = "Time to get orders",
percentiles = {0.5, 0.95, 0.99})
@GetMapping
public List<Order> getOrders() {
return orderService.findAll();
}
}
Для работы @Timed необходимо зарегистрировать TimedAspect:
Пример
@Configuration
public class MetricsConfig {
@Bean
public TimedAspect timedAspect(MeterRegistry registry) {
return new TimedAspect(registry);
}
}
Тэги (Dimensions) — ключевая концепция
Тэги позволяют разбивать метрики по измерениям (dimensions). Одна метрика с разными тэгами даёт множество временных рядов.
Пример
Counter.builder("http.requests")
.tag("method", "GET")
.tag("uri", "/api/orders")
.tag("status", "200")
.register(registry);
Пример
// Общие тэги для всех метрик приложения
@Bean
public MeterRegistryCustomizer<MeterRegistry> commonTags() {
return registry -> registry.config()
.commonTags("service", "order-service")
.commonTags("env", "production")
.commonTags("region", "eu-west-1");
}
Автоматические метрики Spring Boot
| Группа | Метрики | Описание |
|---|---|---|
| JVM | jvm.memory.used, jvm.memory.max, jvm.gc.pause |
Память, GC, потоки |
| HTTP | http.server.requests |
Все HTTP-запросы (метод, URI, статус, время) |
| HikariCP | hikaricp.connections.active, hikaricp.connections.idle |
Пул соединений к БД |
| Kafka | kafka.consumer.records.consumed.total |
Метрики Kafka consumer/producer |
| Cache | cache.gets, cache.puts, cache.evictions |
Метрики кэша |
| Logback | logback.events |
Количество лог-событий по уровням |
| System | system.cpu.usage, process.cpu.usage |
CPU, открытые файлы |
Кастомный MeterBinder
@Component
public class BusinessMetricsBinder implements MeterBinder {
private final OrderRepository orderRepository;
public BusinessMetricsBinder(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
@Override
public void bindTo(MeterRegistry registry) {
Gauge.builder("orders.total.in.db", orderRepository, OrderRepository::count)
.description("Total orders in database")
.register(registry);
}
}
Пример Prometheus-выхода (/actuator/prometheus)
# HELP http_server_requests_seconds Duration of HTTP server request handling
# TYPE http_server_requests_seconds histogram
http_server_requests_seconds_bucket{method="GET",status="200",uri="/api/orders",le="0.1"} 450
http_server_requests_seconds_bucket{method="GET",status="200",uri="/api/orders",le="0.5"} 498
http_server_requests_seconds_bucket{method="GET",status="200",uri="/api/orders",le="+Inf"} 500
http_server_requests_seconds_count{method="GET",status="200",uri="/api/orders"} 500
http_server_requests_seconds_sum{method="GET",status="200",uri="/api/orders"} 12.35
# HELP jvm_memory_used_bytes The amount of used memory
# TYPE jvm_memory_used_bytes gauge
jvm_memory_used_bytes{area="heap",id="G1 Eden Space"} 1.2345678E7
Важное
- Micrometer — фасад, а не реализация. Без подключённого registry (например,
micrometer-registry-prometheus) метрики собираются, но никуда не экспортируются. - Dimensional metrics (тэги) — основа модели Micrometer. В отличие от hierarchical (Graphite-стиль
orders.eu.success), тэги позволяют гибко фильтровать и агрегировать. - Spring Boot 3.x использует Micrometer Observation API — единый механизм для метрик и трейсов одновременно.
Частые ошибки
- Создание метрики при каждом вызове:
Counter.builder(...).register(registry)внутри метода — метрика должна создаваться один раз (в конструкторе или@PostConstruct). - Динамические тэги с высокой кардинальностью:
tag("userId", userId)создаёт отдельный time series для каждого пользователя. - Забыть подключить TimedAspect: без него аннотация
@Timedна кастомных методах не работает (на контроллерах работает через WebMvcMetricsFilter). - Не настроить exposure endpoints: по умолчанию endpoint
/actuator/prometheusне доступен; нужно явно добавить вmanagement.endpoints.web.exposure.include.
Как используется в 2026
- Micrometer Observation API — унифицированный API, одно «наблюдение» автоматически создаёт и метрику, и span трейса.
- Micrometer Context Propagation — автоматическая передача контекста (traceId, MDC) между потоками, включая реактивные цепочки и виртуальные потоки.
- Micrometer 2.x с нативной поддержкой OpenTelemetry Protocol (OTLP) для экспорта метрик напрямую в OTel Collector.
- Большинство Spring Boot-стартеров (Data, Security, Kafka, RabbitMQ) поставляются с автоматическими Observation-хуками.
На собеседовании: ключевой тезис — Micrometer является фасадом (как SLF4J для логов). Покажите, что умеете выбирать тип метрики (Counter vs Gauge vs Timer), знаете про ограничение кардинальности тэгов и понимаете разницу между
@Timedи Observation API в Spring Boot 3.x.