Я работаю над приложением, в котором все время работает около 15 потоков. Недавно мы начали использовать HikariCP для пула соединений.
Эти темы перезапускаются каждые 24 часа. Когда потоки перезапускаются, мы явно закрываем источник данных Hikari, вызывая dataSource.close()
До тех пор, пока мы не начали использовать пул соединений, один объект соединения был передан в потоке всем функциям. Теперь, когда источник данных закрыт и если старый объект connection
уже передан методу, это вернуло ошибку, указав, что источник данных уже закрыт, что имеет смысл.
Чтобы обойти эту проблему, вместо того, чтобы обойти один и тот же объект соединения в потоке, мы начали создавать их в методах класса DBUtils
(в основном функции с запросами)
Так выглядит метод запуска потока в нашем приложении:
@Override
public void run() {
consumer.subscribe(this.topics);
while (!isStopped.get()) {
try {
for (ConsumerRecord<Integer, String> record : records) {
try{
/*some code*/
}catch(JsonProcessingException ex){
ex.printStackTrace();
}
}
DBUtils.Messages(LOGGER.getName(),entryExitList);
} catch (IOException exception) {
this.interrupt();
}
consumer.close();
}
Теперь, после начала использования HikariCP, вместо передачи объекта соединения в DBUtils.Messages
, мы получаем соединение из пула в самом методе
* 1014 то есть *
public static final void Messages(String threadName, List<EntryExit> entryExitMessages) throws SQLException {
Connection connection = DBUtils.getConnection(threadName);
/*code*/
try{
connection.close();
}catch(SQLException se){}
}
Вот как выглядит getConnection
метод DBUtils
public static synchronized Connection getConnection(String threadName) {
Connection connection = null;
try {
if (ds == null || ds.isClosed()) {
config.setJdbcUrl(getProperty("postgres.url"));
config.setUsername(getProperty("postgres.username"));
config.setPassword(getProperty("postgres.password"));
config.setDriverClassName(getProperty("postgres.driver"));
config.setMaximumPoolSize(getProperty("postgres.max-pool-size"));
config.setMetricRegistry(ApplicationUtils.getMetricRegistry());
config.setConnectionTimeout(getProperty("postgres.connection-timeout"));
config.setLeakDetectionThreshold(getProperty("postgres.leak-detection-threshold"));
config.setIdleTimeout(getProperty("postgres.idle-timeout"));
config.setMaxLifetime(getProperty("postgres.max-lifetime"));
config.setValidationTimeout(getProperty("postgres.validation-timeout"));
config.setMinimumIdle(getProperty("postgres.minimum-idle"));
config.setPoolName("PostgresConnectionPool");
ds = new HikariDataSource(config);
}
connection = ds.getConnection();
return connection;
} catch (Exception exception) {
exception.printStackTrace();
}
}
Но поскольку вызов этого метода находится внутри цикла while
в потоке, PostgresConnectionPool.pool.Wait
продолжает увеличиваться.
. Какой лучший способ справиться с этим?
Редактировать: PostgresConnection
- это имя пула. Пул PostgresConnectionPool.pool.Wait
исходит из показателей Dropwizard:
https://github.com/brettwooldridge/HikariCP/wiki/Dropwizard-Metrics