欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Cannot get a connection, pool error Timeout waiting for idle object

程序员文章站 2022-05-30 21:43:21
...
性能测试时,报错org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for idle object,日志中最后的堆栈如下:
Caused by: java.util.NoSuchElementException: Timeout waiting for idle object
at org.apache.tomcat.dbcp.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1171)
at org.apache.tomcat.dbcp.dbcp.AbandonedObjectPool.borrowObject(AbandonedObjectPool.java:79)

at org.apache.tomcat.dbcp.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:106)

我们dbcp的配置

maxActive="30" maxIdle="10" maxWait="10000" removeAbandoned="true" removeAbandonedTimeout="30" testOnBorrow="true" testOnReturn="false" testWhileIdle="true"

查看GenericObjectPool代码

                            if(maxWait > 0 && ((System.currentTimeMillis() - starttime) >= maxWait)) {
                                synchronized(this) {
                                    // Make sure allocate hasn't already assigned an object
                                    // in a different thread or permitted a new object to be created
                                    if (latch.getPair() == null && !latch.mayCreate()) {
                                        // Remove latch from the allocation queue
                                        _allocationQueue.remove(latch);
                                    } else {
                                        break;
                                    }
                                }
                                throw new NoSuchElementException("Timeout waiting for idle object");

可以看到,在我们配置下,是等了超过10秒后,依然没获取到连接,报错,那这种报错有哪些可能呢?可参考这个,1.数据库关闭;2.并发量过高,申请的连接太多导致排队太长,这样总共有部分会等待超时(假设maxWait没配置,默认为500ms)

那我们的是什么问题呢?所有的配置都一样,别的都没问题,那一定是数据库响应太慢,atop查看数据库服务器,IO过高。

对这种错误怎么解决呢?

看需要的结果是什么,如果是普通情况都报错了,那最好是检查一下maxWait是否太短、并发是否太高、是否有过慢的sql导致连接一直无法归还入池;如果正常情况没问题,性能场景有问题,则需要看是否是数据库IO是否正常、是否有过慢sql,配合awr报告等解决;单纯的解决这个错误,可以尝试修改maxWait更长或者为0,等待无限长时间。