连接池异常:无法获取连接,池错误超时等待空闲对象

Posted

技术标签:

【中文标题】连接池异常:无法获取连接,池错误超时等待空闲对象【英文标题】:Connection Pool Exception: Cannot get a connection, pool error Timeout waiting for idle object 【发布时间】:2011-11-08 19:36:24 【问题描述】:

我正在生产环境中运行一个 Web 应用程序,该应用程序最近因承受压力而崩溃。我猜想有 100-300 人在相似的时间访问该网站,我希望这可以正常工作。

崩溃时的日志是:

org.codehaus.groovy.grails.web.taglib.exceptions.GrailsTagException: Error executing tag <g:render>: Hibernate operation: could not inspect JDBC autocommit mode; uncategorize\
d SQLException for SQL [???]; SQL state [null]; error code [0]; Cannot get a connection, pool error Timeout waiting for idle object; nested exception is org.apache.commons.db\
cp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for idle object at /WEB-INF/grails-app/views/layouts/file.gsp:37
        at gsp_file_gsp$_run_closure2.doCall(file_gsp.groovy:43)
        at gsp_file_gsp$_run_closure2.doCall(file_gsp.groovy)
        at gsp_file_gsp.run(gsp_file_gsp.groovy:48)
        at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:190)
        at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:291)
        at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:774)
        at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:703)
        at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:896)
        at java.lang.Thread.run(Thread.java:662)
Caused by: org.springframework.jdbc.UncategorizedSQLException: Hibernate operation: could not inspect JDBC autocommit mode; uncategorized SQLException for SQL [???]; SQL stat\
e [null]; error code [0]; Cannot get a connection, pool error Timeout waiting for idle object; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot get a co\
nnection, pool error Timeout waiting for idle object
        at User.find(User.groovy:68)
        at User$find.call(Unknown Source)
        at gsp_pps_file_gsp.run(gsp_file_gsp.groovy:22)
        ... 9 more
Caused by: org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for idle object
        at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:114)
        at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
        at $Proxy7.getAutoCommit(Unknown Source)
        ... 12 more
Caused by: java.util.NoSuchElementException: Timeout waiting for idle object
        at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1144)
        at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:106)
        ... 14 more

我相信这与我最近添加到我的 Grails 项目中的一些影响连接池的代码直接相关(尽管我相信这不是 Grails 特定的问题):

maxActive = 50
maxIdle = 15
minIdle = 5
initialSize = 15
minEvictableIdleTimeMillis = 180000
timeBetweenEvictionRunsMillis = 180000
maxWait = 10000
validationQuery = "/* ping */"

我做错了什么?请帮忙!谢谢。

【问题讨论】:

我的 maxWait 是不是太低了?我正在阅读文档,这可能是问题所在,但我不能说我对此充满信心。 另外,如果我在 mysql 中使用show processlist;,我只能从我的 Apache 服务器获得 8 个连接。这是否意味着这段代码根本不起作用? 如果我没记错的话,您最初的问题是由于 MySQL 超时,您的池中有一堆死连接。您是否尝试仅设置验证字符串而将其他所有内容保持原样? 您解决了这个问题吗?可以分享一下解决方法吗? 检查是否有任何连接泄漏。查看您的代码***.com/questions/10440391/dbcp-connection-properties/… 【参考方案1】:

将相关部分改为:

minEvictableIdleTimeMillis=1800000
timeBetweenEvictionRunsMillis=1800000
numTestsPerEvictionRun=3
testOnBorrow=true
testWhileIdle=true
testOnReturn=true
validationQuery="SELECT 1"

这应该可以解决这个问题。

【讨论】:

谢谢!这对于 Web 应用程序来说是最优的吗?这是在 MySQL 上测试的吗? 这最初是为 MySQL 准备的,我现在为 PostgreSQL 使用相同的配置。【参考方案2】:

我的代码很糟糕,导致连接的存活时间比应有的时间长。一旦我解决了根本问题,它就消失了。

【讨论】:

你是如何找到有问题的代码的?我看到了仅存在于生产中的相同问题。我们最近添加了一项新功能,当我关闭它时,问题就消失了。不过,新代码并不直接管理数据库连接,所以我不确定它是如何保持连接打开的。我唯一能说的独特之处是新代码在数据库触发方法中执行....afterInsert() 在我的一些域类中。 @ShatyUT 您始终可以使用 VisualVM 之类的分析器(使用适当的插件)跟踪您的连接 - 因此您可以在运行时看到您的连接被打开并且无法关闭特定操作。总帐

以上是关于连接池异常:无法获取连接,池错误超时等待空闲对象的主要内容,如果未能解决你的问题,请参考以下文章

试图识别tomcat中废弃连接的来源

关于MySql8小时空闲后连接超时问题(testOnBorrow,logAbandoned等)

Hibernate c3p0 连接池不会超时空闲连接

数据库连接池

mysql连接超时后无法从apache DBCP连接池获取连接

MySql连接空闲8小时自动断开的原因及连接池配置方法