Проверьте время ожидания активного соединения в пуле соединений Tomcat JDBC.

У нас есть подключение к базе данных postgres, настроенной с помощью tomcat connection pool. Проблема в том, что когда соединение становится активным, оно никогда не возвращается в режим ожидания.

Когда я запускаю свой микросервис, у него 0 активных подключений и 10 незанятых. Через час работы остается 7 активных и 3 неработающих. После выходных было 100 активных, он достиг предела и сервис был недоступен.

Есть ли способ настроить tomcat connection pool для проверки состояния активных соединений и закрытия их, если они застряли?


person Vitalii    schedule 21.05.2018    source источник


Ответы (2)


Похоже, ваше приложение пропускает соединение. По умолчанию hibernate c3p0 предоставляет средства для обнаружения утечек, необходимо настроить два параметра:

5 верно

После этого он напечатает трассировку стека для длинных активных соединений и закроет их.

Рекомендуется не использовать при высокой нагрузке. Если используете другой пул, ищите что-то похожее

person techagrammer    schedule 21.05.2018
comment
Я предполагаю, что проблема в том, что некоторые http-пакеты теряются внутри нашего кластера. В то время как другие люди ищут это, мне нужно добавить обходной путь, прежде чем это будет исправлено. - person Vitalii; 21.05.2018

Так как внутри нашего кластера есть http таймауты, похоже из-за этого происходит утечка соединения. Я исследовал, и соединение остается всегда активным.

Решение для меня состояло в том, чтобы включить проверку заброшенных соединений.

private DataSource configureDataSource(String url, String user, String password, String driverClassName){
    DataSource ds = DataSourceBuilder.create()
            .url(url)
            .username(user)
            .password(password)
            .driverClassName(driverClassName)
            .build();

    org.apache.tomcat.jdbc.pool.DataSource configuredDataSource = (org.apache.tomcat.jdbc.pool.DataSource) ds;

    // some other configurations here
    // ...

    configuredDataSource.getPoolProperties() 
           .setRemoveAbandonedTimeout(300);
    configuredDataSource.getPoolProperties()
           .setRemoveAbandoned(true);
}

@Bean(name = "qaDataSource")
public JdbcTemplate getQaJdbcTemplate()  {
    DataSource ds = configureDataSource(qaURL, qaUsername, qaPassword ,qaDriverClassName);
    return new JdbcTemplate(ds);
}

Флаги RemoveAbandoned и RemoveAbandonedTimeout означают, что если какое-то соединение находится в активном состоянии дольше значения таймаута, оно будет закрыто. Если вы поместите это в свой код, убедитесь, что это время ожидания превышает максимальное время выполнения запроса для вашей службы.

person Vitalii    schedule 22.05.2018