DBCP2 - когда неработающие соединения удаляются из пула
при настройке пула DBCP2 и на основе документация я заметил, что есть конфигурация, которая называется timeBetweenEvictionRunsMillis
описано так:
количество миллисекунд для сна между запусками объекта idle нить evictor. Когда не положительный, нет простоя объекта Thread evictor будет бегать.
значение по умолчанию -1
.
значит ли это, что evictor поток никогда не будет работать в конфигурации по умолчанию? Тогда как параметр конфигурации maxIdle
принудительно-пул должен выселить бездействующие соединения, если их количество больше maxIdle
.
мне кажется очень запутанным, что конфигурация по умолчанию такова, что бездействующие соединения никогда не выселяются.
существует также другая конфигурация softMiniEvictableIdleTimeMillis
который, кажется, играет некоторую роль поверх timeBetweenEvictionRunsMillis
.
любые разъяснения в этом отношении будут иметь огромное значение.
в настоящее время, я настройка пула, как показано ниже - поскольку моя цель-не иметь никаких бездействующих соединений в моем пуле слишком долго (это было необходимо, поскольку мы используем AWS RDS, и, похоже,странный вопрос С ним, с которым мы часто сталкиваемся)
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl(properties.getProperty("app.mysql.url"));
dataSource.setUsername(properties.getProperty("app.mysql.username"));
dataSource.setPassword(properties.getProperty("app.mysql.password"));
dataSource.setMaxIdle(20);
dataSource.setMaxWaitMillis(20000); //wait 10 seconds to get new connection
dataSource.setMaxTotal(200);
dataSource.setMinIdle(0);
dataSource.setInitialSize(10);
dataSource.setTestOnBorrow(true);
dataSource.setValidationQuery("select 1");
dataSource.setValidationQueryTimeout(10); //The value is in seconds
dataSource.setTimeBetweenEvictionRunsMillis(600000); // 10 minutes wait to run evictor process
dataSource.setSoftMinEvictableIdleTimeMillis(600000); // 10 minutes wait to run evictor process
dataSource.setMinEvictableIdleTimeMillis(60000); // 60 seconds to wait before idle connection is evicted
dataSource.setMaxConnLifetimeMillis(600000); // 10 minutes is max life time
dataSource.setNumTestsPerEvictionRun(10);
1 ответов
да, поток evictor не будет работать по умолчанию. Причина в том, что значения maxIdle
и maxTotal
одинаковы по умолчанию, что означает, что не будет никаких соединений для немедленного закрытия и нет необходимости в вытеснении бездействующих соединений. Таким образом, пул просто экономит некоторые ресурсы, не запуская бесполезный поток.
но когда вы меняетесь maxIdle
и сделать ее ниже, чем maxTotal
без запуска потока evictor, это не значит, что ваши связи не будут закрыты. Он значит они будут закрыты сразу после освобождения, без задержки, пока их количество не упадет до maxIdle
.
а то minEvictableIdleTimeMillis
и softMinEvictableIdleTimeMillis
приходите играть (будьте осторожны, в документации есть опечатка, это ...MinEvictalbe...
, а не ...MiniEvictable...
). Разница между ними в том, что первые не уважают minIdle
в то время как последний не делает. Это немного сложно, учитывая тот факт, что softMinEvictableIdleTimeMillis
проверяется только при minEvictableIdleTimeMillis
истек.
предположим, что мы есть minEvictableIdleTimeMillis=10000
и softMinEvictableIdleTimeMillis=-1
(по умолчанию). В этом случае простое соединение будет оставаться в пуле не более 10 секунд. Даже если количество соединений не превышает minIdle
, он будет закрыт. Если это приведет к падению количества соединений ниже minIdle
, новое соединение будет создано немедленно.
теперь, предположим, что у нас есть minEvictableIdleTimeMillis=10000
и softMinEvictableIdleTimeMillis=30000
. В таком случае простое соединение после проверки на minEvictableIdleTimeMillis
и обнаружение превышения будет дополнительно проверено на softMinEvictableIdleTimeMillis
. Если время простоя превышает его, соединение будет закрыто. В противном случае он будет сидеть в бассейне до следующей положительной проверки против minEvictableIdleTimeMillis
.
в конце концов, у вас будут связи между maxTotal
и maxIdle
закрыто немедленно, соединения между maxIdle
и minIdle
закрытые после minEvictableIdleTimeMillis
и соединений между minIdle
и 0
закрытые после softMinEvictableIdleTimeMillis
и сразу же возобновлено. Плюс-минус чек на выселение период.
С вашей конфигурацией, вы будете иметь все соединения закрыты немедленно, в то время как пул больше, чем 20. И эти 20 соединений будут жить от 10 до 20 минут (даже если они простаивают), потому что у вас есть 10 минут обоих EvictableIdleTimeMillis
плюс 10 минут TimeBetweenEvictionRunsMillis
.
я хотел бы также упомянуть потенциальную проблему с большим разрывом между maxIdle
и maxTotal
. Если вы ожидаете, что maxIdle
будет превышаться очень часто, лучше его увеличить. Иначе, вы столкнетесь с постоянными открытиями и закрытиями соединений, которые создадут дополнительное давление на вашу базу данных (потому что создание нового соединения с БД является относительно тяжелой операцией) и сетевую инфраструктуру сервера приложений (потому что закрытые соединения будут висеть в состоянии TIME_WAIT, истощая пул сетевых портов).