Пул соединений Tomcat JDBC медленный - PullRequest
0 голосов
/ 06 сентября 2018

У меня есть веб-приложение, которое работает на Tomcat 9. Некоторое время я использовал один объект JDBC Connection для обработки всех запросов, но я знал, что в будущем мне придется изменить его на пул соединений. Что ж, этот день настал, и теперь приложение работает значительно медленнее (почти в 3 раза медленнее). Единственная разница между быстрой сборкой и медленной сборкой заключается в использовании пула соединений, и я могу последовательно генерировать одинаковые результаты. Тестирование проводится в тех же системах с одинаковыми конфигурациями (например, ведение журнала).

Приложение не слишком интенсивно использует базу данных, поэтому разница во времени обработки транзакций меня удивляет. Без пула соединений транзакция (которая имеет 2 обращения к веб-службе, что приводит к максимуму 2 чтениям БД и 2 записи БД) занимает 5 секунд для обработки. При использовании пула соединений та же самая последовательность вызовов занимает 15 секунд.

Код для восстановления соединения:

import java.sql.Connection;
import java.sql.SQLException;
import org.apache.tomcat.jdbc.pool.DataSource;
import org.apache.tomcat.jdbc.pool.PoolProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class UsernamePasswordConnectionRetriever implements IConnectionRetriever {

    private static final Logger LOGGER = LoggerFactory.getLogger(UsernamePasswordConnectionRetriever.class);
    private final DataSource datasource;

    public UsernamePasswordConnectionRetriever(String driver, String url, String username, String password) {
        PoolProperties p = new PoolProperties();
        p.setUrl(url);
        p.setDriverClassName(driver);
        p.setUsername(username);
        p.setPassword(password);
        p.setJmxEnabled(false);
        p.setTestWhileIdle(false);
        p.setTestOnBorrow(false);
        p.setValidationQuery("SELECT 1");
        p.setTestOnReturn(false);
        p.setValidationInterval(90000);
        p.setTimeBetweenEvictionRunsMillis(30000);
        p.setMaxActive(200);
        p.setInitialSize(2);
        p.setMaxWait(0);
        p.setRemoveAbandonedTimeout(60);
        p.setMinEvictableIdleTimeMillis(30000);
        p.setMinIdle(10);
        p.setLogAbandoned(true);
        p.setRemoveAbandoned(true);
        p.setJdbcInterceptors(
          "org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"+
          "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");
        datasource = new DataSource();
        datasource.setPoolProperties(p);
    }   

    @Override
    public Connection getConnection() throws SQLException {
        LOGGER.debug("DB connection pool info: {} active, {} idle", datasource.getNumActive(), datasource.getNumIdle());
        return datasource.getConnection();
    }

}

Метод getConnection вызывается вызывающей стороной в блоке try-with-resources , при этом соединение является ресурсом, поэтому я знаю, что оно закрывается. Кроме того, я всегда вижу одну и ту же запись в журнале « Информация о пуле соединений БД: 0 активных, 2 незанятых », что обеспечивает дополнительную гарантию того, что соединения не остаются открытыми.

Я играл с некоторыми вариантами этих сеттеров, но до сих пор не видел реальных изменений в производительности. Я также отключил ведение журнала slf4j, и эта разница была почти незначительной.

Какой-нибудь совет, как мне повысить производительность и при этом использовать пул соединений?

Редактировать Я должен добавить, что используемая здесь база данных - MySQL, и система тестируется на Windows Server 2016. Мы также проводим тестирование на Linux, но результаты, которые я опубликовал, получены с тестового сервера Windows.

...