Gymterview
middle

Как настроить пул соединений HikariCP для PostgreSQL?

HikariCP — высокопроизводительный пул соединений для JDBC, используемый по умолчанию в Spring Boot. Пул переиспользует готовые соединения, снижая задержки (создание TCP-соединения ~5-10 мс) и нагрузку на PostgreSQL (~10 МБ RAM на каждое соединение).

Настройка в application.yml

Пример
spring:
  datasource:
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
      connection-timeout: 30000       # таймаут ожидания соединения из пула (мс)
      idle-timeout: 600000            # время жизни неактивного соединения (мс)
      max-lifetime: 1800000           # максимальное время жизни соединения (мс)
      pool-name: BankAppPool
      leak-detection-threshold: 60000 # предупреждение при удержании > 60 сек
      data-source-properties:
        prepareThreshold: 5
        preparedStatementCacheQueries: 256
        preparedStatementCacheSizeMiB: 5

Формула размера пула

Оптимальный размер пула обычно значительно меньше, чем ожидают. Формула от авторов HikariCP:

Пример
pool_size = количество_ядер_CPU * 2 + количество_дисков

Для сервера с 4 ядрами и 1 SSD: 4 * 2 + 1 = 9 соединений. Этого достаточно для тысяч запросов в секунду.

Мониторинг HikariCP

Конфигурация метрик
@Configuration
public class HikariMetricsConfig {

    @Bean
    public HikariDataSource dataSource(DataSourceProperties properties,
                                        MeterRegistry meterRegistry) {
        HikariDataSource ds = properties.initializeDataSourceBuilder()
                .type(HikariDataSource.class).build();
        ds.setMetricRegistry(meterRegistry);
        return ds;
    }
}

Ключевые метрики

  • hikaricp.connections.active — активные соединения
  • hikaricp.connections.idle — простаивающие соединения
  • hikaricp.connections.pending — потоки, ожидающие соединение (если > 0, пул мал)
  • hikaricp.connections.timeout.total — количество таймаутов получения соединения

Типичные проблемы

  • connection-timeout срабатывает — пул исчерпан: увеличить пул или оптимизировать время транзакций
  • max-lifetime должен быть меньше idle_in_transaction_session_timeout на PostgreSQL и меньше таймаута файервола/балансировщика
  • Утечка соединений — включить leak-detection-threshold для обнаружения

На собеседовании: формула размера пула — обязательный ответ. Покажите, что 10 соединений хватает для тысяч rps, а 100 соединений — это антипаттерн, который замедлит PostgreSQL из-за контекстных переключений. Метрика pending > 0 — сигнал к действию.