Could not get JDBC Connection问题排查

2020-10-23   58 次阅读


Could not get JDBC Connection排查

最近在开发一个项目,发现总是隔一段时间JDBC就报错:
Could not get JDBC Connection; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for idle object

DBCP连接池的自我检测

默认配置的DBCP连接池,是不对池中的连接做测试的,有时连接已断开了,但DBCP连接池不知道,还以为连接是好的呢。
应用从池中取出这样的连接访问数据库一定会报错。这也是好多人不喜欢DBCP的原因

解决方案(查看是否缺少且添加如下配置项):

# 验证连接是否可用,使用的SQL语句
validationQuery = "SELECT 1"  
# 指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除.
testWhileIdle = "true"      
# 借出连接时不要测试,否则很影响性能
testOnBorrow = "false"   
# 每30秒运行一次空闲连接回收器
timeBetweenEvictionRunsMillis = "30000"  
# 池中的连接空闲30分钟后被回收,默认值就是30分钟。
minEvictableIdleTimeMillis = "1800000"  
# 在每次空闲连接回收器线程(如果有)运行时检查的连接数量,默认值就是3.
numTestsPerEvictionRun="3" 

解释

  • 配置timeBetweenEvictionRunsMillis = "30000"后,每30秒运行一次空闲连接回收器(独立线程)。并每次检查3个连接,如果连接空闲时间超过30分钟就销毁。销毁连接后,连接数量就少了,如果小于minIdle数量,就新建连接,维护数量不少于minIdle,过行了新老更替。

  • testWhileIdle = "true" 表示每30秒,取出3条连接,使用validationQuery = "SELECT 1" 中的SQL进行测试 ,测试不成功就销毁连接。销毁连接后,连接数量就少了,如果小于minIdle数量,就新建连接。

  • testOnBorrow = "false" 一定要配置,因为它的默认值是true。false表示每次从连接池中取出连接时,不需要执行validationQuery = "SELECT 1" 中的SQL进行测试。若配置为true,对性能有非常大的影响,性能会下降7-10倍。所在一定要配置为false.

  • 每30秒,取出numTestsPerEvictionRun条连接(本例是3,也是默认值),发出"SELECT 1" SQL语句进行测试 ,测试过的连接不算是“被使用”了,还算是空闲的。连接空闲30分钟后会被销毁。

文章参考来源

博客参考地址:https://www.iteye.com/blog/elf8848-1931778
官方文档:http://commons.apache.org/proper/commons-dbcp/configuration.html

Q.E.D.

知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

那一年,我也变成了光!!