Короткий ответ
Нужно проверить скрытые источники насыщения, которые не отражаются в CPU/памяти: пулы соединений (к БД, к внешним API), очереди запросов, диск I/O и сетевые задержки, а также посмотреть, не деградировала ли latency конкретно у одной из зависимостей сервиса.
Как это работает подробнее
рост latency при нормальных CPU/памяти часто означает, что запросы "ждут" — в очереди на пул соединений к БД, на ответ от медленного внешнего API, на блокировку (lock) в базе данных, либо на диск при высоком I/O wait. Эти метрики не видны на стандартном дашборде ресурсов узла.
Пример / кейс
Ожидаемое поведение: если метрика близка к 1 (пул почти полностью занят), запросы начинают ждать свободное соединение — это объясняет рост latency без роста CPU; решение — увеличить пул (с учётом лимитов самой БД) или найти медленные запросы, удерживающие соединения.
Пример кода
# Утилизация пула соединений к БД приложения
app_db_pool_active_connections / app_db_pool_max_connectionsЧто использовать на практике
- Практический подход. Проверяют метрики пула соединений (утилизация, количество ожидающих), трассировку запросов (distributed tracing) для определения, на каком именно вызове растёт время, метрики самой БД (медленные запросы, блокировки) и сетевые метрики (retransmits, DNS resolution time). Полезно сравнить latency по перцентилям (p50 vs p99) — рост только p99 указывает на "хвостовые" задержки у части запросов, а не общую перегрузку.
Подводные камни
- Частые ошибки. Останавливаться на проверке только CPU/памяти узла и делать вывод "ресурсов достаточно, проблема не у нас"; не иметь трассировки запросов и из-за этого не понимать, на каком шаге цепочки растёт задержка; игнорировать метрики самой БД/внешних зависимостей.