惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Cloudflare Blog
阮一峰的网络日志
阮一峰的网络日志
Martin Fowler
Martin Fowler
D
DataBreaches.Net
The GitHub Blog
The GitHub Blog
人人都是产品经理
人人都是产品经理
V
V2EX
爱范儿
爱范儿
PCI Perspectives
PCI Perspectives
T
Troy Hunt's Blog
Stack Overflow Blog
Stack Overflow Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
SecWiki News
SecWiki News
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
The Hacker News
The Hacker News
小众软件
小众软件
雷峰网
雷峰网
D
Docker
NISL@THU
NISL@THU
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
腾讯CDC
B
Blog RSS Feed
C
CERT Recently Published Vulnerability Notes
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
U
Unit 42
有赞技术团队
有赞技术团队
P
Palo Alto Networks Blog
G
GRAHAM CLULEY
T
The Exploit Database - CXSecurity.com
T
Tailwind CSS Blog
S
Security @ Cisco Blogs
量子位
I
InfoQ
Application and Cybersecurity Blog
Application and Cybersecurity Blog
大猫的无限游戏
大猫的无限游戏
Schneier on Security
Schneier on Security
Help Net Security
Help Net Security
Latest news
Latest news
The Register - Security
The Register - Security
S
Securelist
W
WeLiveSecurity
A
Arctic Wolf
Security Latest
Security Latest
AWS News Blog
AWS News Blog
L
LINUX DO - 热门话题
S
Secure Thoughts
T
Tenable Blog
Know Your Adversary
Know Your Adversary
月光博客
月光博客
M
MIT News - Artificial intelligence

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Оптимизируем JDBC connection pool HikariCP. Основы и настройка
Растегаев Юрий · 2026-05-04 · via Все публикации подряд на Хабре

Средний

8 мин

12K

Привет, Хабр!

HikariCP вполне можно назвать де-факто стандартом JDBC connection pooling в современной JVM-экосистеме: он используется по умолчанию в Spring Boot, часто выбирается в Java, Kotlin и Scala-проектах, активно поддерживается и хорошо знаком DevOps/SRE-командам по метрикам и поведению.

Типичная конфигурация пула выглядит примерно следующим образом:

Пример конфигурации
val config = new HikariConfig()
config.setJdbcUrl(url)
config.setUsername(user)
config.setPassword(password)
config.setMaximumPoolSize(connectionPoolMaxSize)
config.setLeakDetectionThreshold(1000)
config.setAutoCommit(true)
sslRootCert.foreach(config.addDataSourceProperty("sslrootcert", _))

new HikariDataSource(config)

И конфиг:

Пример HOCON-конфига
db.jdbc {
  dataSource {
    url = ${?DATASOURCE_URL}
    user = ${?DB_USER}
    password = ${?DB_PASSWD}
  }

  connectionPool {
    maxSize = 32
    maxSize = ${?DB_CONNECTION_SIZE}
  }
}

Вроде не ужас. HikariCP есть, размер пула вынесен в переменную окружения, пароль не захардкожен в боевом конфиге, SSL-сертификат поддерживается. Можно жить.

Но если смотреть на это пристальнее, то возникают вопросы:

  1. Почему пул именно 32 или 42 или 52?

  2. Что будет, если база или сетевой балансировщик закрывает соединения раньше, чем Hikari?

  3. Сколько ждать свободное соединение: 30 секунд по умолчанию или меньше?

  4. Видим ли мы метрики пула?

  5. Работает ли leakDetectionThreshold = 1000, или мы просто успокаиваем себя красивой строчкой?

Погнали разбираться. В этой части — что такое HikariCP, где он живёт, какие версии актуальны и как задаёт минимальный и типовой конфиг. Во второй части разберём размер пула, Kubernetes/PgBouncer, доработаем конфиг из начала, типовые ошибки и продовый чеклист.


1. HikariCP: что это вообще такое

Определение

HikariCP это JDBC connection pool.

JDBC тут ключевое слово. HikariCP не привязан к одному языку или фреймворку. Это библиотека для JVM, которая управляет JDBC-соединениями. Поэтому она одинаково естественно живёт в Java, Kotlin, Scala, Groovy, Clojure и вообще в любом языке, который в итоге работает поверх JVM и JDBC.

Что делает пул
  • заранее открывает несколько соединений к базе;

  • выдаёт соединение коду, когда надо выполнить запрос;

  • принимает соединение обратно после close();

  • следит за жизненным циклом соединений;

  • ограничивает количество одновременных походов в базу;

  • даёт метрики, чтобы понять, где приложение упёрлось в БД.

Без пула каждый запрос мог бы создавать новое физическое соединение. Это дорого: TCP, TLS, аутентификация, настройка сессии, иногда ещё и прокси между приложением и базой. С пулом приложение берёт уже готовое соединение, работает и возвращает его обратно.

Пул не ускоряет сам SQL, он ограничивает и упорядочивает доступ к базе

Главная мысль, которую легко пропустить: пул не ускоряет сам SQL. Он ограничивает и упорядочивает доступ к базе. Хорошо настроенный пул делает систему стабильнее. Плохо настроенный пул умеет очень красиво положить базу, особенно если у вас 20 pod’ов и в каждом maximumPoolSize = 50.


2. Где используют HikariCP

Java

В Java-мире HikariCP давно стал вариантом “по умолчанию”. В Spring Boot он используется как дефолтный JDBC pool, если в classpath есть spring-boot-starter-jdbc или spring-boot-starter-data-jpa.

Kotlin

В Kotlin всё то же самое. Если проект на Spring Boot или Ktor с JDBC/Exposed, HikariCP обычно подключается через стандартную конфигурацию.

Scala

В Scala его можно встретить рядом с Quill, Slick, ScalikeJDBC, ZIO, Akka. Смысл тот же: HikariDataSource передают в контекст выбранной database-библиотеки или регистрируют в обёртке над DataSource.

Groovy

В Groovy это Grails, Spring Boot, plain JDBC-скрипты и сервисы.

Clojure

В Clojure HikariCP используют через next.jdbc, hikari-cp и похожие обёртки.

Python, Go, Node.js и Ruby

В Python, Go, Node.js и Ruby HikariCP обычно не используют, потому что там нет JDBC как базового слоя. Там свои пулы: database/sql в Go, SQLAlchemy QueuePool в Python, pg.Pool в Node.js и так далее.


3. Версии на апрель 2026

По Maven Central и репозиторию проекта актуальная основная линия HikariCP: 7.0.x, последняя версия, которую я нашёл, 7.0.2.

Важный момент по совместимости

Современный артефакт HikariCP рассчитан на Java 11+. Старые Java 8-проекты не надо механически тащить на 7.x. Для них нужно отдельно смотреть совместимую ветку и ограничения своего фреймворка.

Крупные вехи
  • 3.4.5 - старая, но ещё встречается в живых проектах. Релиз 2020 года.

  • 4.x - эпоха Java 8/11-перехода, появился keepaliveTime.

  • 5.x - уже более современная линия для новых JVM-стеков.

  • 6.x - много внутренних исправлений, включая работу с credentials и JDBC lifecycle.

  • 7.x - актуальная major-линия, Java 11+, исправления вокруг reflection, credentials provider, interruption в pool filling loop.

Осторожно с virtual threads

А теперь ложка дёгтя. В апреле 2026 я бы аккуратно смотрел на HikariCP 7.0.2 в проектах с virtual threads. Есть открытые обсуждения про CPU saturation в сценариях с большим количеством virtual threads, где соединения активно берутся и возвращаются в пул. Это не значит “не обновляться никогда”. Это значит: если у вас Java 21, virtual threads и высокий DB-throughput, обновление надо прогонять под нагрузкой, а не только через unit-тесты.

Для обычного JVM-сервиса без virtual threads история проще: смотрим совместимость JVM и фреймворка, обновляемся на поддерживаемую версию, запускаем нагрузочный тест.


4. Минимальная настройка в разных JVM-языках

Начнём с голого HikariCP, без Spring Boot магии.

Java

Пример настройки HikariCP на Java
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

import javax.sql.DataSource;

public final class DataSourceFactory {
    public static DataSource create() {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl(System.getenv("DB_URL"));
        config.setUsername(System.getenv("DB_USER"));
        config.setPassword(System.getenv("DB_PASSWORD"));

        config.setPoolName("app-postgres");
        config.setMaximumPoolSize(16);
        config.setMinimumIdle(16);
        config.setConnectionTimeout(5_000);
        config.setValidationTimeout(2_000);
        config.setMaxLifetime(25 * 60_000);
        config.setKeepaliveTime(2 * 60_000);
        config.setAutoCommit(true);

        return new HikariDataSource(config);
    }
}

Kotlin

Пример настройки HikariCP на Kotlin
import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import javax.sql.DataSource

fun dataSource(): DataSource {
    val config = HikariConfig().apply {
        jdbcUrl = System.getenv("DB_URL")
        username = System.getenv("DB_USER")
        password = System.getenv("DB_PASSWORD")

        poolName = "app-postgres"
        maximumPoolSize = 16
        minimumIdle = 16
        connectionTimeout = 5_000
        validationTimeout = 2_000
        maxLifetime = 25 * 60_000
        keepaliveTime = 2 * 60_000
        isAutoCommit = true
    }

    return HikariDataSource(config)
}

Scala

Пример настройки HikariCP на Scala
import com.zaxxer.hikari.{HikariConfig, HikariDataSource}

object DataSourceFactory {
  def create(): HikariDataSource = {
    val config = new HikariConfig()
    config.setJdbcUrl(sys.env("DB_URL"))
    config.setUsername(sys.env("DB_USER"))
    config.setPassword(sys.env("DB_PASSWORD"))

    config.setPoolName("app-postgres")
    config.setMaximumPoolSize(16)
    config.setMinimumIdle(16)
    config.setConnectionTimeout(5000)
    config.setValidationTimeout(2000)
    config.setMaxLifetime(25 * 60 * 1000)
    config.setKeepaliveTime(2 * 60 * 1000)
    config.setAutoCommit(true)

    new HikariDataSource(config)
  }
}

Синтаксис разный, смысл один: HikariCP это один и тот же HikariConfig и HikariDataSource, просто обёрнутые в привычный язык.


5. Если у вас Spring Boot

В Spring Boot обычно не надо руками создавать HikariDataSource. Достаточно настроек:

Пример настройки HikariCP в Spring Boot
spring:
  datasource:
    url: jdbc:postgresql://db.example.local:5432/app
    username: ${DB_USER}
    password: ${DB_PASSWORD}
    hikari:
      pool-name: app-postgres
      maximum-pool-size: 16
      minimum-idle: 16
      connection-timeout: 5000
      validation-timeout: 2000
      max-lifetime: 1500000
      keepalive-time: 120000
      auto-commit: true
      register-mbeans: true
Полезные метрики HikariCP

Если включён Spring Boot Actuator и Micrometer, метрики Hikari обычно можно получить без большого шаманства. Самые полезные:

  • hikaricp.connections.active - сколько соединений сейчас занято;

  • hikaricp.connections.idle - сколько свободно;

  • hikaricp.connections.pending - сколько потоков ждут соединение;

  • hikaricp.connections.timeout - сколько раз приложение не дождалось соединения;

  • hikaricp.connections.acquire - сколько времени занимает получение соединения;

  • hikaricp.connections.usage - как долго соединение держат.

Без метрик настройка пула превращается в догадки: кажется, что всё работает, пока не начались таймауты и очередь за соединениями.


6. Главные параметры HikariCP

maximumPoolSize

Максимальное количество соединений в пуле. Включает и занятые, и свободные.

Если пул достиг этого размера, а свободных соединений нет, поток будет ждать до connectionTimeout. Потом получит ошибку.

Самая частая ошибка: ставить maximumPoolSize по количеству пользователей или HTTP-потоков. База не становится быстрее от того, что вы открыли к ней 100 соединений. Часто становится медленнее: контекстные переключения, конкуренция за CPU, locks, память, лишняя нагрузка на планировщик.

minimumIdle

Минимальное количество свободных соединений, которое Hikari старается держать.

Если minimumIdle не задан, HikariCP по умолчанию делает его равным maximumPoolSize. Получается fixed-size pool: все соединения создаются и держатся тёплыми.

Для серверных приложений с предсказуемой нагрузкой это часто нормальный вариант. Меньше сюрпризов на всплесках. Если хотите динамический пул, задавайте minimumIdle ниже maximumPoolSize, но понимайте цену: новые соединения могут создаваться прямо во время нагрузки.

connectionTimeout

Сколько ждать свободное соединение из пула.

Дефолт HikariCP: 30 секунд. Для многих backend-сервисов это слишком долго. Если запрос 30 секунд стоит в очереди за соединением, пользователь уже давно не счастлив, а ваш HTTP thread занят и держит ресурсы.

Я обычно начинаю с 2-5 секунд для online API и отдельно думаю про batch/background jobs.

validationTimeout

Сколько ждать проверки соединения. Дефолт: 5 секунд.

Если база или сеть деградирует, длинные проверки могут добавить неприятную задержку. 1-2 секунды часто достаточно, но надо смотреть на сеть и географию.

idleTimeout

Сколько idle-соединение может лежать в пуле перед удалением.

Работает только если minimumIdle < maximumPoolSize. Если пул fixed-size, параметр почти не участвует в жизни.

maxLifetime

Максимальный возраст соединения.

Это один из самых важных параметров для прода. Он должен быть меньше таймаута, после которого соединение может прибить база, proxy, load balancer, firewall или managed cloud-инфраструктура.

Если инфраструктура закрывает соединения через 30 минут, ставить maxLifetime = 30m плохо. Лучше 25-29 минут, в зависимости от конкретного окружения. Hikari сам добавляет небольшое размазывание по времени, чтобы не убивать весь пул разом.

keepaliveTime

Периодическая проверка idle-соединений, чтобы инфраструктура не считала их мёртвыми.

Появился не в самых древних версиях, поэтому если у вас HikariCP 3.4.5, пора посмотреть changelog и совместимость. В современных версиях дефолт около 2 минут. Значение должно быть меньше maxLifetime.

leakDetectionThreshold

Через сколько миллисекунд Hikari логирует предупреждение, что соединение слишком долго не вернули в пул.

Дефолт: 0, то есть выключено. Минимальное значение для включения: 2000 мс.

И вот тут возвращаемся к конфигу из начала статьи:

config.setLeakDetectionThreshold(1000)

Выглядит как “ловим утечки быстрее”. На деле в современных HikariCP значение меньше 2 секунд не считается валидным. То есть такая настройка может быть просто отключена валидацией. Обидный случай: строчка есть, а пользы нет.

В проде я бы не держал короткий leak detection постоянно. Он может шуметь на нормальных длинных запросах. Лучше включать временно при расследовании или ставить порог выше ожидаемого p99 использования соединения.


Вместо вывода:

Во второй части разберём выбор размера пула (формула из PostgreSQL/Hikari wiki, закон Литтла, метрики), суммирование соединений по репликам и связку с Kubernetes, роль PgBouncer, доработку «типового» конфига из примера, полный HOCON и Scala-код, типовые ошибки, мини-чеклист для прода и полезные ссылки.


Вторая часть https://habr.com/ru/articles/1031770/


Если вам близки темы разработки, рефакторинга, архитектуры и стартапов, буду рад видеть вас в моём Telegram-канале.

Успешных вам релизов!