Как посмотреть эффективность использования соединений в connection pool и состояние очереди при получении соединения
Что проверяют
Сможете ли вы доказать, что тормозит именно пул, а не база или код, и отличить «пул мал» от «соединения держат слишком долго». Следом обычно спрашивают, какой размер пула вы бы выставили и почему увеличение maximumPoolSize помогает не всегда.
Как отвечать
В Spring Boot пул по умолчанию HikariCP, и метрики он отдаёт через Micrometer без дополнительного кода. С Actuator они видны в /actuator/metrics и уходят в Prometheus:
hikaricp.connections.activeиhikaricp.connections.idle: сколько соединений занято и сколько свободно;hikaricp.connections.pending: потоки, ждущие соединение. Это и есть состояние очереди;hikaricp.connections.acquire: таймер времени получения соединения из пула;hikaricp.connections.usage: сколько соединение держат от получения до возврата;hikaricp.connections.timeout: счётчик тех, кто так и не дождался.
Без Micrometer есть JMX: spring.datasource.hikari.register-mbeans=true, и в VisualVM или JConsole появится MBean пула с ActiveConnections, IdleConnections и ThreadsAwaitingConnection. Из кода то же отдаёт HikariDataSource.getHikariPoolMXBean(). Уровень DEBUG для com.zaxxer.hikari раз в 30 секунд пишет в лог строку со статистикой пула.
Интерпретация важнее списка метрик. Если pending постоянно больше нуля и растёт acquire, смотрите на usage. Долгое удержание указывает на код: длинные транзакции, HTTP-вызовы внутри @Transactional, включённый по умолчанию spring.jpa.open-in-view, при котором соединение может держаться до конца запроса. Утечки ловит leakDetectionThreshold: он пишет стек, где соединение взяли и не вернули. Со стороны PostgreSQL картину дополняет pg_stat_activity, особенно сессии в idle in transaction.
Где спотыкаются
Сразу увеличивают пул. Если соединения держат долго, больший пул лишь переносит очередь в базу, а десять инстансов по 50 соединений упрутся в max_connections.
Путают таймауты: connectionTimeout (по умолчанию 30 секунд) это ожидание соединения из пула, а не таймаут SQL-запроса.
Смотрят на active без pending. Полностью занятый пул без очереди работает нормально.