Вопрос:
У меня есть приложение Spring Boot, которое предоставляет API REST для интерфейсов. Я использую jOOQ и Postgresql. В настоящее время я получаю эту ошибку при локальном тестировании всех тестов интеграции (около 1000 тестов, это начинается после выполнения 700-800 тестов):
org.postgresql.util.PSQLException: FATAL: sorry, too many clients already
Я пытался ограничить максимальные свободные и активные соединения с помощью application.properties, но кажется, что эти значения несколько игнорируются. Я просто контролирую открытые соединения при выполнении тестов с помощью этого утверждения:
SELECT datname, state, query FROM pg_stat_activity;
Вот как выглядит мое приложение application.properties:
spring.datasource.driverClassName = org.postgresql.Driver spring.datasource.url = jdbc:postgresql://localhost:5432/xxx spring.datasource.username = xxx spring.datasource.password = xxx spring.datasource.initialize = true spring.datasource.continue-on-error = false spring.jooq.sql-dialect = POSTGRES spring.datasource.max-active = 50 spring.datasource.max-idle = 5
Вот как я создаю свой источник данных:
@ConfigurationProperties(prefix = «spring.datasource») @Bean public DataSource dataSource() { return DataSourceBuilder .create() .build(); }
Я вижу, что jOOQ использует правильный источник данных, и соединение обрабатывается jOOQ должным образом (получение и освобождение соединения от источника данных). Поэтому проблема не должна быть на стороне jOOQ.
У меня max_connections = 200 в моем postgresql.conf, поэтому моя конфигурация Spring должна быть прекрасной. Во время выполнения тестов я вижу гораздо больше pg_stat_activity соединений в pg_stat_activity чем указано в моей конфигурации. В конце концов, когда тесты начинают сбой из-за этого PSQLException я вижу около 90-100 простоя подключений в pg_stat_activity. Таким образом, возникают две проблемы:
- Почему мои тесты терпят неудачу, хотя моя локальная база данных должна допускать больше соединений, чем то, что я вижу в pg_stat_activity?
- Кажется, что конфигурация источника данных в моих application.properties игнорируется. Любая идея почему?
Лучший ответ:
Так как не было предложенного ответа, я публикую свое решение. Краткая версия: уменьшите размер пула соединений в свойствах теста:
spring.datasource.hikari.maximum-pool-size=2
Более длинная версия: Spring Boot 2 по умолчанию использует HikariCP для пула соединений, значение по умолчанию которого равно 10 для размера пула соединений (по состоянию на январь 2019 года). При работе большого количества ИТ-ресурсов контекст Spring создается несколько раз, что означает, что каждый контекст получает 10 соединений из базы данных. Насколько я заметил, тесты распределяют соединения быстрее, чем они освобождаются. Следовательно, в какой-то момент достигается предел max_connections разрешенный сервером базы данных (который по умолчанию обычно равен 100), что приводит к этой ошибке “слишком много клиентов”.
Ограничив размер пула соединений до 2 в свойствах теста, я смог решить эту проблему.