我有一个在Tomcat 9上运行的Web应用程序。一段时间以来,我一直在使用单个JDBC Connection对象来处理所有请求,但是我知道以后必须将其更改为连接池。好了,这一天到了,现在应用程序的运行速度大大降低了(几乎快了三倍)。快速构建和慢速构建之间的唯一区别是使用连接池,我可以始终如一地生成相同的结果。测试是在具有完全相同的配置(例如,日志记录)的完全相同的系统上进行的。
该应用程序不是数据库密集型应用程序,因此事务处理时间的差异令我感到惊讶。如果没有连接池,则事务(对Web服务进行2次调用,最多导致2次DB读取和2次DB写)需要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 块中调用,连接是资源,因此我知道它正在关闭。此外,我总是看到相同的日志条目“ DB连接池信息:0处于活动状态,2处于空闲状态”,以便进一步确保连接不会保持打开状态。
我尝试过这些二传手的一些变体,但仍然没有看到任何真正的改变。我还关闭了slf4j日志记录,这种差异几乎可以忽略不计。
关于如何获得更好的性能并仍然使用连接池的任何建议?
编辑我应该补充一点,此处使用的数据库是MySQL,并且该系统正在Windows Server 2016机器上进行测试。我们也在Linux上进行测试,但我发布的结果全部来自Windows测试服务器。