Происходит следующее: ваше приложение пытается получить соединение с БД из пула, и оно истекает через 30 секунд (по умолчанию), поскольку больше нет доступных соединений (все они используются).
Вы устанавливаете какое-либо из этих значений для Hikari или просто принимаете значения по умолчанию?
datasource:
hikari:
connection-init-sql: SELECT 1
connection-test-query: SELECT 1
auto-commit: true
connection-timeout: 3000
idle-timeout: 600000
leak-detection-threshold: 45000
max-lifetime: 1800000
maximum-pool-size: 10
validation-timeout: 5000
Чтобы найти вашу проблему, я предлагаю вам сделать две вещи:
- Включить обнаружение утечки:
leak-detection-threshold: 45000
, и это выведет оператор журнала, подобный следующему:
2020-02-07 18:16:26,100 WARN HikariPool-1 housekeeper ProxyLeakTask.? - Connection leak detection triggered for org.postgresql.jdbc.PgConnection@2dda7a8e on thread https-jsse-nio-8458-exec-11, stack trace follows
java.lang.Exception: Apparent connection leak detected
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:128)
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
at org.hibernate.internal.NonContextualJdbcConnectionAccess.obtainConnection(NonContextualJdbcConnectionAccess.java:38)
at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:104)
at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getPhysicalConnection(LogicalConnectionManagedImpl.java:134)
at org.hibernate.internal.SessionImpl.connection(SessionImpl.java:462)
at jdk.internal.reflect.GeneratedMethodAccessor206.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:282)
at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:266)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle.doGetConnection(HibernateJpaDialect.java:430)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.beginTransaction(HibernateJpaDialect.java:174)
at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:402)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:376)
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:572)
...
Это скажет вам, где в вашем приложении процессы, которые удерживают соединения более 45 секунд. Вы можете изменить на 30, если хотите.
включите этот отладчик в своем логгере:
logging:
level:
com.zaxxer.hikari.pool.HikariPool: DEBUG
, который будет так часто регистрировать подобные операторы:
2020-02-07 04:17:38,798 DEBUG HikariPool-1 housekeeper HikariPool.logPoolState - HikariPool-1 - Pool stats (total=10, active=1, idle=9, waiting=0)
Когда активный равен общему количеству, которое вы знаете Ваш пул используется в полной мере, и вы увидите, что число ожидающих увеличится. По сути, в этот момент вам нужен любой процесс, который пропускает соединения, чтобы освободить соединения или перезапустить ваше приложение. В противном случае вы начнете видеть эти ошибки.
Также следует отметить, что 30 секунд (по умолчанию) - это долгое время ожидания истечения времени ожидания соединения. Если это запрос от веб-страницы, помните, что есть реальный пользователь, ожидающий 30 секунд (большинство людей слишком нетерпеливы, чтобы ждать так долго), чтобы что-то произошло. Как вы можете видеть в нашем приложении, мы установили его на 3000 мс (или 3 секунды).