# Гайд по метрикам и мониторингу ## Быстрый старт 1. **Запуск:** ```bash docker compose up -d ``` 2. **Доступ к сервисам:** - Приложение: http://localhost:8080 - Prometheus: http://localhost:9090 - Grafana: http://localhost:3000 (логин: admin, пароль: admin) 3. **Дашборды:** - Открой Grafana → Home → Dashboards - Два дашборда загружены автоматически: - **Spring Boot Application Metrics** — HTTP, JVM, CPU, GC - **PostgreSQL & HikariCP Monitoring** — connection pool, база данных 4. **Создай нагрузку для проверки:** ```bash # Создать задачу curl -X POST http://localhost:8080/api/tasks \ -H "Content-Type: application/json" \ -d '{"title":"Test","description":"Load test","completed":false}' # Посмотреть метрики появятся в Grafana через 5-15 секунд ``` ## Основные метрики ### HTTP метрики **Что смотреть:** - `http_server_requests_seconds_count` — количество запросов - `http_server_requests_seconds_sum` — суммарное время выполнения - `http_server_requests_seconds_bucket` — распределение времени ответа **Зачем:** - Отслеживать нагрузку на эндпоинты - Находить медленные запросы (p95, p99) - Видеть ошибки по статус-кодам **Пример запроса в Prometheus:** ```promql # Request rate по эндпоинтам rate(http_server_requests_seconds_count{application="todo"}[1m]) # 95-й перцентиль времени ответа histogram_quantile(0.95, sum(rate(http_server_requests_seconds_bucket[5m])) by (le, uri)) # Количество ошибок 5xx sum(rate(http_server_requests_seconds_count{status=~"5.."}[1m])) ``` ### JVM метрики **Что смотреть:** - `jvm_memory_used_bytes` — используемая память (heap/non-heap) - `jvm_memory_max_bytes` — максимальная доступная память - `jvm_gc_pause_seconds` — время на GC паузах - `jvm_threads_live_threads` — количество потоков **Зачем:** - Проверить утечки памяти (постоянный рост heap) - Оптимизировать GC (частые паузы = проблема) - Контролировать создание потоков **Алерты:** ```promql # Память heap больше 80% (jvm_memory_used_bytes{area="heap"} / jvm_memory_max_bytes{area="heap"}) > 0.8 # GC паузы больше 100ms rate(jvm_gc_pause_seconds_sum[1m]) > 0.1 ``` ### Database Connection Pool (HikariCP) **Что смотреть:** - `hikaricp_connections_active` — активные соединения - `hikaricp_connections_idle` — простаивающие соединения - `hikaricp_connections_pending` — ожидающие потоки - `hikaricp_connections_timeout_total` — таймауты соединений - `hikaricp_connections_acquire_seconds` — время получения соединения **Зачем:** - Настроить размер пула (если active = max постоянно, увеличить) - Найти медленные запросы (высокое usage time) - Обнаружить connection leaks (timeouts растут) **Оптимальные значения:** - Active connections < 70% от max - Acquire time < 10ms (p95) - Pending threads = 0 - Timeouts = 0 **Алерты:** ```promql # Пул заполнен больше 80% (hikaricp_connections_active / hikaricp_connections_max) > 0.8 # Таймауты соединений rate(hikaricp_connections_timeout_total[1m]) > 0 # Медленное получение соединений (p95 > 50ms) histogram_quantile(0.95, rate(hikaricp_connections_acquire_seconds_bucket[1m])) > 0.05 ``` ### System метрики **Что смотреть:** - `system_cpu_usage` — CPU системы - `process_cpu_usage` — CPU процесса - `disk_free_bytes` — свободное место на диске **Зачем:** - Контролировать нагрузку на CPU - Предотвратить переполнение диска ## Использование Grafana ### Навигация по дашбордам 1. **Spring Boot Application Metrics:** - HTTP Request Rate — количество запросов в секунду по эндпоинтам - HTTP Request Duration — время ответа (p95, p99) - HTTP Status Codes — распределение статус-кодов - JVM Memory — использование heap/non-heap памяти - Database Connection Pool — состояние пула соединений - JVM Threads — количество потоков - GC Pause Time — время на сборку мусора - System CPU Usage — нагрузка на CPU 2. **PostgreSQL & HikariCP Monitoring:** - Connection Pool Status — статистика пула (active, idle, total, pending) - Connection Pool Utilization — процент использования пула - Connection Acquire Time — время получения соединения (перцентили) - Connection Timeout Count — количество таймаутов - Connection Creation Time — время создания нового соединения - Connection Usage Time — среднее время использования соединения ### Полезные функции Grafana **Time Range:** - Последние 5 минут — реал-тайм мониторинг - Последний час — анализ недавних инцидентов - Последние 24 часа — дневные паттерны **Refresh:** - 5s — активный мониторинг - 30s — обычный режим - Off — анализ истории **Zoom:** - Выдели область на графике для zoom-in - Двойной клик — zoom-out **Legend:** - Клик на метрику — скрыть/показать - Shift+клик — изолировать метрику ## Практические сценарии ### 1. Медленный эндпоинт **Признаки:** - Request Duration (p95) > 1s для конкретного URI - Connection Acquire Time растет **Диагностика:** ```promql # Найти медленный эндпоинт topk(5, histogram_quantile(0.95, sum(rate(http_server_requests_seconds_bucket[5m])) by (le, uri))) # Проверить время получения соединения histogram_quantile(0.95, rate(hikaricp_connections_acquire_seconds_bucket[1m])) ``` **Решение:** - Оптимизировать SQL запрос - Добавить индексы - Включить кеширование ### 2. Memory Leak **Признаки:** - Heap memory постоянно растет - Частые Full GC паузы - OutOfMemoryError в логах **Диагностика:** ```promql # Рост памяти jvm_memory_used_bytes{area="heap"} # Частота GC rate(jvm_gc_pause_seconds_count[1m]) ``` **Решение:** - Heap dump анализ (jmap) - Проверить кеши и коллекции - Закрывать ресурсы (connections, streams) ### 3. Connection Pool Exhausted **Признаки:** - Active connections = Max connections - Pending threads > 0 - Timeouts растут - Медленные запросы **Диагностика:** ```promql # Утилизация пула (hikaricp_connections_active / hikaricp_connections_max) * 100 # Ожидающие потоки hikaricp_connections_pending # Таймауты rate(hikaricp_connections_timeout_total[1m]) ``` **Решение:** - Увеличить `spring.datasource.hikari.maximum-pool-size` - Найти медленные запросы - Проверить connection leaks (незакрытые соединения) ### 4. Высокая нагрузка **Признаки:** - Request rate резко вырос - CPU usage > 80% - Response time увеличилось **Диагностика:** ```promql # Request rate sum(rate(http_server_requests_seconds_count[1m])) # CPU system_cpu_usage # Response time histogram_quantile(0.95, sum(rate(http_server_requests_seconds_bucket[5m])) by (le)) ``` **Решение:** - Горизонтальное масштабирование (больше инстансов) - Rate limiting - Кеширование частых запросов ## Настройка алертов (опционально) Создай файл `prometheus-alerts.yml`: ```yaml groups: - name: app_alerts interval: 30s rules: - alert: HighErrorRate expr: rate(http_server_requests_seconds_count{status=~"5.."}[1m]) > 0.1 for: 1m labels: severity: critical annotations: summary: "High 5xx error rate" - alert: HighMemoryUsage expr: (jvm_memory_used_bytes{area="heap"} / jvm_memory_max_bytes{area="heap"}) > 0.9 for: 2m labels: severity: warning annotations: summary: "JVM heap usage > 90%" - alert: ConnectionPoolExhausted expr: (hikaricp_connections_active / hikaricp_connections_max) > 0.9 for: 1m labels: severity: critical annotations: summary: "Connection pool almost full" - alert: SlowEndpoint expr: histogram_quantile(0.95, sum(rate(http_server_requests_seconds_bucket[5m])) by (le, uri)) > 2 for: 5m labels: severity: warning annotations: summary: "Endpoint p95 latency > 2s" ``` Добавь в `prometheus.yml`: ```yaml rule_files: - /etc/prometheus/prometheus-alerts.yml ``` ## Best Practices 1. **Регулярно проверяй метрики** — открывай Grafana хотя бы раз в день 2. **Настрой алерты** — получай уведомления о проблемах 3. **Анализируй тренды** — сравнивай метрики по неделям 4. **Документируй инциденты** — записывай что пошло не так и как исправил 5. **Тестируй под нагрузкой** — используй JMeter/Gatling + метрики для нагрузочного тестирования 6. **Не игнорируй warning** — маленькие проблемы перерастают в большие ## Полезные PromQL запросы ```promql # Top 5 медленных эндпоинтов topk(5, histogram_quantile(0.95, sum(rate(http_server_requests_seconds_bucket[5m])) by (le, uri))) # Request rate по методам sum(rate(http_server_requests_seconds_count[1m])) by (method) # Error rate % (sum(rate(http_server_requests_seconds_count{status=~"[45].."}[1m])) / sum(rate(http_server_requests_seconds_count[1m]))) * 100 # Memory growth rate (MB/hour) rate(jvm_memory_used_bytes{area="heap"}[1h]) * 3600 / 1024 / 1024 # Database connection wait time sum(rate(hikaricp_connections_pending[1m])) # Thread count trend jvm_threads_live_threads - jvm_threads_live_threads offset 1h ```