HikariPool-1 - Соединение недоступно, время запроса истекло после 30000 мс для очень маленького загрузочного сервера
У меня есть небольшое Java-приложение для тестирования. Я недавно переехал в Хикари. Что я заметил, так это то, что я продолжаю получать эту ошибку.
java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30000ms.
java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30000ms.
at com.zaxxer.hikari.pool.HikariPool.createTimeoutException(HikariPool.java:602)
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:195)
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:145)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:85)
Ниже приведены мои настройки для хикари изначально.
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/****");
config.setUsername("***");
config.setPassword("*****");
config.setMaximumPoolSize(20);
Едва ли это используются мои два устройства, и я завершаю к концу, я действительно закрываю его. Так что я не знаю, почему он продолжает получать ошибку? В чем может быть проблема или есть какие-то настройки, которые мне нужно изменить?
14 ответов
Ваша база данных не получает соединение в течение (30000 миллисекунд, что является свойством по умолчанию connectionTimeout) из-за задержки в сети или некоторых запросов, выполнение которых занимает слишком много времени (более 30000 миллисекунд).
Пожалуйста, попробуйте увеличить стоимость имущества connectionTimeout
,
Пример конфигурации YML:
spring:
datasource:
hikari:
minimumIdle: 2
maximumPoolSize: 10
idleTimeout: 120000
connectionTimeout: 300000
leakDetectionThreshold: 300000
Пример конфигурации Java:
HikariConfig config = new HikariConfig();
config.setMaximumPoolSize(20);
config.setConnectionTimeout(300000);
config.setConnectionTimeout(120000);
config.setLeakDetectionThreshold(300000);
Я использую пружинную загрузку, и я столкнулся с той же проблемой, и моим решением было получить такое соединение "DataSourceUtils.getConnection(dataSource)
". Я перехожу с dataSource.getConnection()
к DataSourceUtils.getConnection(dataSource)
.
В моем случае код не закрывал соединения.
Попытка с ресурсами исправила это:
try (
Connection connection = dataSource.getConnection()
...
В моем случае я использовал JPA и, следовательно, использовал EntityManagerFactory для сохранения и запроса для моего проекта SpringBoot и получил ту же ошибку.
Причина заключалась в том, что в любой операции CRUD я не закрывал EntityManager после завершения операции, что приводило к истощению ресурсов.
Надеюсь это поможет!!
EntityManager em = emf.createEntityManager();
Customer c = em.find(Customer.class , id);
em.close();
Я исправил свою проблему, используя:
увеличить minIdle и maxPool
spring.datasource.hikari.minimumIdle=20
spring.datasource.hikari.maximumPoolSize=30
spring.datasource.hikari.connectionTimeout=50000
Чтобы отладить проблему/проверить правильность значений, включите ведение журнала для Hikari:
logging.level.com.zaxxer.hikari.HikariConfig=DEBUG
logging.level.com.zaxxer.hikari=TRACE
Журналы будут выглядеть так:
DEBUG 2023-01-06T16:12:31.932018849Z HikariPool-1 - Before cleanup stats (total=17, active=0, idle=17, waiting=0)
DEBUG 2023-01-06T16:12:31.932665522Z HikariPool-1 - After cleanup stats (total=17, active=0, idle=17, waiting=0)
DEBUG 2023-01-06T16:12:31.932733949Z HikariPool-1 - Fill pool skipped, pool is at sufficient level.
DEBUG 2023-01-06T16:12:32.495269726Z HikariPool-1 - After adding stats (total=17, active=0, idle=17, waiting=0)
DEBUG 2023-01-06T16:12:38.309953158Z HikariPool-1 - Fill pool skipped, pool is at sufficient level.
DEBUG 2023-01-06T16:12:39.200246897Z HikariPool-1 - Fill pool skipped, pool is at sufficient level.
DEBUG 2023-01-06T16:12:44.812065268Z HikariPool-1 - Before cleanup stats (total=18, active=0, idle=18, waiting=0)
DEBUG 2023-01-06T16:12:44.812822113Z HikariPool-1 - After cleanup stats (total=18, active=0, idle=18, waiting=0)
Удачи ! :)
В моем случае:
o.h.engine.jdbc.spi.SqlExceptionHelper: HikariPool-1 - Connection is not available, request timed out after 30019ms.
i.s.commons.web.error.ExceptionLogger: Internal Server Error
org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection
Был вызван слишком низкимspring.hikari.maximumPoolSize
в свойствах приложения, увеличиваясь от5
к20
решил проблему. Сообщение журнала является своего рода промахом.
Это также может произойти, если клиентское приложение запрашивает много открытых подключений, а параметр сервера базы данных имеет максимальное ограничение на количество подключений к пулу. Таким образом, клиентское приложение больше не может получать соединения с сервером базы данных. Проверьте пул подключений к серверу базы данных, чтобы увидеть, не превышено ли максимальное значение в течение периода времени ошибок.
тайм-аут запроса - это не то, что вы можете исправить, увеличив тайм-аут. Возможно, вам нужно будет оценить все запросы от вашего сервиса и реализовать индексацию, если это необходимо.
Как правило, открытые и незакрытые соединения вызывают эту проблему. Существует ограничение на количество серверов приложений для подключения к базе данных, и если вы превысите это ограничение, это приведет к сбою вашей среды.
Соединение должно стоять на одноэлементном шаблоне, но если вам действительно нужно открыть источник данных или подключить внешний источник данных, например отчеты, вы должны закрыть свое соединение в своем окончательном блоке, где вы открываете блок соединения.
connection.getConnection().rollback();
connection.getConnection().close();
Вы также должны закрыть, если используете PersistenceJpa без синглтона.
persistenceJPAConfig.dataSource().getConnection().rollback();
persistenceJPAConfig.dataSource().getConnection().close();
Если вы используете некоторые инструменты стресс-тестирования, создавая потоки для проверки своих методов, вы, вероятно, получите эту ошибку в своих запросах, которые занимают много времени. Это приведет к оптимизации ваших запросов или размера экземпляра службы.
Обязательно закройте использованные соединения.
Простой способ сделать это в Котлине:
dataSource.connection.use { connection ->
// Your code here
}
вечность, чтобы понять это ... В моем случае я использовал решение, подобное Andrés Rincón :
try (Connection connection = DataSourceUtils.getConnection(jdbcTemplate.getDataSource())) {
// some code here
}
В моем случае я увеличил размерhikaripoolConnection
до 10, и это было решено.
В моем случае я использовал решение, похожее на @Andres Rincon:
try (Connection conn = connectionManager.getDataConnection()) {
Statement stmt = conn.createStatement();
...
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
Что исправило проблему в моем случае, так это добавить правильную индексацию в соответствующие таблицы базы данных. Взгляните на запросы/транзакции, которые вы делаете в БД.
В моем случае оператор, который вызывал задержку, был оператором UPDATE, например
UPDATE table_name WHERE column1 = value1, column2 = value2;
Что исправило проблему для меня в этом случае, так это добавить индекс в эту таблицу для этих двух столбцов, например:
CREATE INDEX index_name ON table_name (column1, column2);
Еще одна веская причина может заключаться в том, что вы не закрываете свои соединения . Вы можете закрыть соединения с помощью инструкции try-with-resource, например:
try( Connection connection = datasource.getConnection() ){
//your code
}
На мой взгляд, увеличение тайм-аута, как предложил Гирдхар Сингх Ратор, не идеально. Это может временно решить проблему, но в какой-то момент вам нужно будет позаботиться о правильной индексации и управлении закрытием соединений.
Надеюсь это поможет.