TGViewer
Библиотека джависта | Java, Spring, Maven, Hibernate Библиотека джависта | Java, Spring, Maven, Hibernate @javaproglib · 22K subscribers
Post #7689 2.61K
⚙️ HikariCP в проде: пять настроек, которые часто крутят неправильно

Пул соединений в Spring Boot работает «из коробки», поэтому в application.properties обычно либо пусто, либо строчка про размер пула. И всё хорошо ровно до первого пика, когда в логах начинает мелькать Connection is not available, request timed out after 30000ms, а сервис уходит в полупаралич: не падает, но и не работает.

Разбираем параметры, которые чаще всего настроены не так.

1️⃣ maximumPoolSize: «больше» ≠ «лучше»

Классика — поставить 100 «на всякий, у нас тысяча юзеров онлайн». Но каждый коннекшн к Postgres — это процесс на стороне БД, память, контекст транзакции. 100 параллельных запросов от одного бэкенда — это не параллельность, а очередь: CPU и диск всё равно одни.

Формула из pool sizing guide самого HikariCP: connections = (core_count * 2) + effective_spindle_count

Для 8 ядер + SSD это ~17 коннекшенов. И помни про реплики: 5 подов по 20 = 100 коннекшенов к одной базе только от этого сервиса, а у Postgres max_connections обычно 100–200. Перешагнул → FATAL: sorry, too many clients already.

Прежде чем раздувать пул, загляни в pg_stat_activity. В 9 из 10 случаев там медленные запросы без индекса, idle in transaction или локи. Больше коннекшенов = больше параллельных медленных запросов.

2️⃣ minimumIdle = maximumPoolSize, а не половине

Туториалы любят min-idle: 5 / max: 20 → «в холостом держим 5, в пик расширяемся». Звучит экономно, а на деле каждый новый коннекшн — это TCP + TLS + auth + инициализация сессии = 30–100 мс сверху на первые запросы при расширении. Спайк на старте дня → красивый пик p99 → ложный инцидент.

HikariCP проектировался как фиксированный пул. Дефолт minimumIdle == maximumPoolSize, и автор прямо просит не трогать. Хочешь экономить — уменьшай maximumPoolSize, а не разноси его с minimumIdle.

3️⃣ maxLifetime: всегда меньше любого внешнего таймаута

Дефолт 30 минут. Проблема: если что-то в инфраструктуре закроет коннекшн раньше, чем HikariCP его «состарит», ловишь Connection is closed.

А закрыть может многое:
▪️ AWS NLB — idle TCP через 350 сек
▪️ AWS ALB — 60 сек
▪️ корпоративный фаервол — 5–15 мин, без логов
▪️ PgBouncer server_idle_timeout — 600 сек
▪️ Postgres idle_in_transaction_session_timeout — нередко 10 мин

Ставь с запасом 30–60 сек меньше самого короткого внешнего таймаута. Не видишь внешних таймаутов — 300000 (5 мин) разумный дефолт.

4️⃣ keepaliveTime: чтобы коннекшн не протух в idle

Дефолт 0 → выключено. В средах с агрессивным conntrack или короткими idle-таймаутами файрвола соединение тихо рвётся, и следующий клиент получает Broken pipe / Connection reset на первом же запросе.

Включаешь — и HikariCP раз в N мс гоняет SELECT 1 по простаивающим коннекшенам.
spring.datasource.hikari:
keepalive-time: 30000 # 30 сек
max-lifetime: 300000 # keepalive ОБЯЗАТЕЛЬНО меньше

Минимум — 30 сек, меньше HikariCP проигнорит. Нагрузка копеечная: 20 коннекшенов = 40 пингов в минуту.

5️⃣ connectionTimeout: это твой SLA

Дефолт 30 сек — почти всегда абсурд. Если API должно отвечать за 500 мс, клиент через 30 сек уже давно получил 504 от ingress. А бэкенд продолжает копить запросы, потоки висят в ожидании коннекшна, сервис застревает на минуты.

Лучше fail fast:
spring.datasource.hikari.connection-timeout: 2000  # 2 сек

Пул исчерпан → быстрый 503, очередь не растёт, алерт срабатывает сразу. Сверху можно навесить circuit breaker (Resilience4j).

⚠️ actuator/health/db дёргает базу. При исчерпанном пуле он тоже встаёт в очередь → DOWN → k8s liveness рестартит под → нагрузка переезжает на соседей → каскад. Лечится коротким connectionTimeout + liveness, который не трогает базу вообще.

И главное помни: HikariCP — это просто пул. Если в сервисе медленные запросы без индексов, ни твики таймаутов, ни раздувание пула не помогут — получишь больше параллельных медленных запросов, и база встанет ещё быстрее. Сначала pg_stat_activity, pg_stat_statements, EXPLAIN ANALYZE — потом настройка пула.

══════ Навигация ══════
Вакансии • Задачи • Собесы

🐸 Библиотека джависта

#Enterprise
  • 🔥 11
  • ❤ 7
  • 👍 5
More from @javaproglib
  1. Oct 12, 2026👀 Как вы смотрите видео? Разбираете урок, слушаете интервью фоном или начинаете на телефо…
  2. Oct 10, 2026Post #7892
  3. Oct 10, 2026Read. Write. Edit. Bash. Это базовый набор операций Pi — агента, на котором построен OpenC…
  4. Oct 2, 2026🎹 Что делать после ChatGPT? Следующий шаг — AI-агенты. Они не просто отвечают на запросы,…
  5. Sep 30, 2026🔥 Последний день для разработчиков AI уже пишет код. Теперь важнее научиться встраивать е…
  6. Sep 30, 2026🫡 Шпаргалка по аннотациям Spring Boot @Autowired, @RestController, @Transactional, @Cache…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →