← Назад к вопросам
Как работает сбор метрик в Java?
2.0 Middle🔥 231 комментариев
#REST API и микросервисы
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как работает сбор метрик в Java?
Метрики — это количественные измерения производительности и состояния приложения (CPU, память, количество запросов, время обработки и т.д.). В Java существует несколько подходов к их сбору.
1. JMX (Java Management Extensions)
Это встроенный механизм мониторинга в Java.
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.ThreadMXBean;
public class JMXMetricsCollector {
public static void collectMemoryMetrics() {
MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
long heapUsed = memoryBean.getHeapMemoryUsage().getUsed();
long heapMax = memoryBean.getHeapMemoryUsage().getMax();
long heapUsedPercent = (heapUsed * 100) / heapMax;
System.out.println("Heap Memory Used: " + heapUsed / (1024 * 1024) + " MB");
System.out.println("Heap Memory Max: " + heapMax / (1024 * 1024) + " MB");
}
public static void collectThreadMetrics() {
ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
int threadCount = threadBean.getThreadCount();
System.out.println("Current Threads: " + threadCount);
}
}
2. Micrometer — универсальный фасад для метрик
Micrometer позволяет отправлять метрики в различные системы (Prometheus, Grafana, CloudWatch).
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.Timer;
import org.springframework.stereotype.Component;
@Component
public class ApplicationMetrics {
private final MeterRegistry meterRegistry;
private final Counter requestCounter;
private final Timer requestTimer;
public ApplicationMetrics(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
this.requestCounter = Counter.builder("http.requests.total")
.description("Total number of HTTP requests")
.register(meterRegistry);
this.requestTimer = Timer.builder("http.requests.duration")
.description("HTTP request duration")
.register(meterRegistry);
}
public void recordRequest() {
requestCounter.increment();
}
}
3. Spring Boot Actuator с Micrometer
Автоматический сбор метрик в Spring Boot.
management:
endpoints:
web:
exposure:
include: metrics,prometheus,health
metrics:
export:
prometheus:
enabled: true
Dostup через endpoints:
- GET /actuator/metrics — список всех метрик
- GET /actuator/prometheus — экспорт в формате Prometheus
4. Собственные метрики
@Service
public class UserService {
private final MeterRegistry meterRegistry;
private final AtomicInteger activeUsers = new AtomicInteger(0);
public UserService(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
Gauge.builder("users.active", activeUsers::get)
.register(meterRegistry);
}
public void loginUser(String userId) {
activeUsers.incrementAndGet();
meterRegistry.counter("user.login").increment();
}
}
5. Перехватчик для HTTP метрик
@Component
public class MetricsInterceptor implements HandlerInterceptor {
private final MeterRegistry meterRegistry;
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) {
Timer.Sample sample = Timer.start(meterRegistry);
request.setAttribute("timerSample", sample);
return true;
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
Timer.Sample sample = (Timer.Sample) request.getAttribute("timerSample");
if (sample != null) {
sample.stop(Timer.builder("http.request.duration")
.tag("method", request.getMethod())
.tag("status", String.valueOf(response.getStatus()))
.register(meterRegistry));
}
}
}
6. AOP для автоматического сбора метрик
@Aspect
@Component
public class MetricsAspect {
private final MeterRegistry meterRegistry;
@Around("@annotation(io.micrometer.core.annotation.Timed)")
public Object measureExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
String methodName = joinPoint.getSignature().getName();
long startTime = System.currentTimeMillis();
try {
return joinPoint.proceed();
} finally {
long duration = System.currentTimeMillis() - startTime;
meterRegistry.timer("method.execution.time",
"method", methodName)
.record(duration, java.util.concurrent.TimeUnit.MILLISECONDS);
}
}
}
@Service
public class PaymentService {
@Timed
public void processPayment(String orderId) {
// Время выполнения будет автоматически записано
}
}
7. Типы метрик
| Тип | Назначение | Пример |
|---|---|---|
| Counter | Счётчик (только +) | Количество запросов |
| Gauge | Текущее значение | Активные пользователи |
| Timer | Время выполнения | Длительность запроса |
| Histogram | Распределение | Размер ответов |
8. Интеграция с Prometheus
global:
scrape_interval: 15s
scrape_configs:
- job_name: myapp
metrics_path: /actuator/prometheus
static_configs:
- targets: ["localhost:8080"]
Лучшие практики
- Используйте Micrometer — стандарт в современном Java
- Экспортируйте в Prometheus — один из лучших хранилищ
- Визуализируйте в Grafana — создавайте дашборды
- Не перегружайте метриками — собирайте только нужные
- Используйте теги — для фильтрации и агрегации
- Мониторьте бизнес-метрики — активные пользователи, конверсия
- Устанавливайте alerts — оповещение при аномалиях
Таким образом, сбор метрик — это критический компонент для мониторинга здоровья приложения.