`
san_yun
  • 浏览: 2652395 次
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多

线上tomcat服务器报错:


 

现象:

应用在高峰来临的时候报大量报下面的错误。

  1. org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is   
  2.         org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for  idle object  
  3.         at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:204 )  
  4.         at org.springframework.orm.ibatis.SqlMapClientTemplate.executeWithListResult(SqlMapClientTemplate.java:249 )  
  5.         at org.springframework.orm.ibatis.SqlMapClientTemplate.queryForList(SqlMapClientTemplate.java:296 )  
  6.   
  7. ...................  
  8.   
  9. Caused by: org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for  idle object  
  10.         at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:114 )  
  11.         at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044 )  
  12.         at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:113 )  
  13.         at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:190 )  
  14.         ... 33  more  
  15. Caused by: java.util.NoSuchElementException: Timeout waiting for  idle object  
  16.         at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1134 )  
  17.         at org.apache.commons.dbcp.AbandonedObjectPool.borrowObject(AbandonedObjectPool.java:79 )  
  18.         at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:106 )  
  19.         ... 36  more  

 

分析错误来源:


查看出错部分源码,发现出现这个问题出现的原因是数据库操作时超时了。

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


查看dbcp的数据源配置如下:

  1. <property name= "maxWait" ><value> 60000 </value></property>  
  2. <property name="maxIdle" ><value> 14 </value></property>  


超时时间为60s,而调用量top的sql响应时间平均都在2~3ms左右,所以主要时间消耗应该是出现在获取数据库连接上面。

 

查看出现问题时的线程情况,发现线程有个大量的增长,多出了很多个数据库调用的线程,而数据库的连接池仅有14个,而等待队列用的是一个linkedList,及无限队列,如果调用量很大,队列过长,确实会出现大量60stimeout的情况。

 

然后查找线程池大量增长的原因。应用中有一个对外提供的接口,调用量比较大,而且接口中需要去好几个地方取数据,所以采用了多线程的方式来提高速度,线程池的配置如下。

  1. executor =  new  ThreadPoolExecutor( 10 50 3 , TimeUnit.SECONDS,  
  2.                                           new  ArrayBlockingQueue<Runnable>( 200 ));  
  3. executor.setRejectedExecutionHandler(new  ThreadPoolExecutor.CallerRunsPolicy());  

corePoolSize=10

maxPoolSize=50

队列类型长度:ArrayBlockingQueue 200

reject策略:CallerRunsPolicy

 

首 先前10个线程都通过threadFactory.newThread(w)获取新线程来跑,当池已经到达corePoolSize,则会把任务放入到队 列中,已有线程通过获取队列中的任务来执行。当队列放满之后,再来新任务,则会继续通过threadFactory.newThread(w)获取新线程 来执行,直到池到达50(maxPoolSize)。如果这个时候还有任务过来,则会按照设置的rejectedExecutionHandler的策略 来执行(详细可查看ThreadPoolExecutor中的excute方法)。

rejectedExecutionHandler策略很简单,通过调用线程来执行。

当高并发的时候,线程池已经达到max并且队列已满,则确实会出现一个线程的大量增长。

 

  1. public   static   class  CallerRunsPolicy  implements  RejectedExecutionHandler {  
  2.         public   void  rejectedExecution(Runnable r, ThreadPoolExecutor e) {  
  3.             if  (!e.isShutdown()) {  
  4.                 r.run();  
  5.             }  
  6.         }  
  7.     }  

 

推断:


高峰来的时候,首先的时候导致数据库调用的线程池增大,整体数据库调用的响应变慢,导致接口的多线程处理部分线程处理速度变慢,任务堆积,直到线程池和队列都满掉,直接通过工作线程来启动,导致更多线程来获取数据库连接线程,队列更长,知道最后,超过60s。

 

解决:


其实解决很好解决的,这个接口里面存在一个方法误用,本来这种大量调用的接口就不应该直接走数据库的,改成走缓存,问题解决。

 

  • 大小: 179.8 KB
分享到:
评论

相关推荐

    dbcp 连接池不合理的锁导致连接耗尽解决方案

    在提供的堆栈跟踪中,可以看到`NoSuchElementException: Timeout waiting for idle object`异常,这通常表示线程在等待连接池中的空闲连接时超时,即没有在预设时间内获取到连接。这可能是因为: 1. **连接池大小...

    確保 Web AP 不會從 Glassfish Connection Pool 取到關閉的連線1

    确保 Web AP 不會從 Glassfish Connection Pool 取到關閉的連線 ...通过設置連線驗證、連線 timeout 和連線池大小,可以保證 Web AP 不會從 Connection Pool 中獲取關閉的連線,從而提高系統的穩定性和性能。

    Codis jar包修改过RoundRobinJedisPool代码的for循环

    系统使用了codis之后,发现当并发量上来之后,会抛出异常:could not get resource from pool,更底层的原因是:Timeout waiting for idle object 修改了RoundRobinJedisPool代码将for循环内部的代码控制到原子 jar...

    ConnectionPool 数据库连接池

    try (Connection conn = dataSource.getConnection()) { // 执行SQL语句 } catch (SQLException e) { e.printStackTrace(); } } ``` **五、优化策略** 1. **合理设置连接池参数**:如初始化连接数、最小空闲...

    idle-timeout:idle-timeout是一个npm软件包。 一旦允许系统在空闲状态下持续一定时间,就会弹出超时弹出窗口

    空闲超时弹出该项目是使用版本9.0.7生成的。开发服务器为开发服务器运行ng serve 。... 如果您更改任何源文件,该应用程序将自动重新加载。代码脚手架运行ng generate component component-name生成一个新的组件。...

    Python库 | django-session-idle-timeout-1.3.0.tar.gz

    《Python库 Django-session-idle-timeout的深度解析》 在Python的世界里,Django作为一款强大的Web框架,因其高效、易用和丰富的功能而备受开发者喜爱。而在Django的生态系统中,有一个名为`django-session-idle-...

    Python IDLE 错误:IDLE”s subprocess didn”t make connection 的解决方案

    Either IDLE can't start a subprocess or personal firewall software is blocking the connection. 错误截图:   错误原因分析: 同层目录下存在和Python库文件相同名字的.py文件,导致子进程无法创建的问题。 ...

    connectionPool:Java数据库连接池

    4. 获取和释放连接:使用`dataSource.getConnection()`获取连接,完成后调用`Connection.close()`归还连接,实际不会关闭,而是放回连接池。 5. 关闭连接池:在应用关闭时,调用`dataSource.close()`关闭连接池。 ...

    USB4 1.0 ECN - CL0s Exit Timeout.pdf

    USB4 1.0 ECN - CL0s Exit Timeout USB4 1.0 版本的 ECN(Engineering Change Notice)文件对 CL0s 退出 timeout 进行了修改,以下是相关知识点的总结: 1. CL0s 退出 timeout 的添加:在退出 CL0s 状态时,添加了...

    mysql.data.dll

    - Idle connection pool cleanup. We now use a timer thread to clean up dead connections from the connection pool. - Command timeout has been refactored to use network and stream timeouts instead of a ...

    java中常见的错误.docx

    15. 数据库连接池异常:`Timeout waiting for idle object`提示获取数据库连接超时,可能是连接池配置不当或资源耗尽。 16. 结果集关闭:`Operation not allowed after ResultSet closed`再次强调结果集必须在正确...

    mysql连接的空闲时间超过8小时后 MySQL自动断开该连接解决方案

    修改 /etc/mysql/my.cnf文件,在 [mysqld] 节中设置: # Set a connection to wait 8hours in idle status. wait_timeout =86400 相关参数,红色部分 mysql&gt; show variables like ‘%timeout%’; +————————...

    MySQL数据库连接超时(Wait_timeout)问题总结.pdf

    对于Hibernate,可以通过设置`hibernate.connection.pool_size`和`hibernate.c3p0.idle_test_period`等属性来调整连接池大小和检测空闲连接的频率。 总之,MySQL的连接超时问题主要是由`wait_timeout`参数引发的,...

    Adb uiautomator XML 解析, 脚本开发必备利器 模拟器/真机通用

    大家使用uiautomator dump 来获取界面元素xml后。基本都是用取文本中间或正则来分析的。这样不但效率低下,对一些特征不明显的xml元素很难取到。如果直接用xml来匹配就不存在这个问题了。并且可以基于本框架进行快速...

    App idle in .net

    在.NET框架中,"App idle"(应用空闲)是一个重要的概念,特别是在处理用户界面(UI)或桌面应用程序时。这个术语通常指的是程序在一段时间内没有接收到任何用户输入或执行任何显著操作的状态。理解如何检测和管理...

    GTK进阶学习:定时器 源代码

    在GTK中,定时器主要通过`g_timeout_add()`或`g_idle_add()`函数来实现。这两个函数都属于GLib库,而GLib是GTK的基础。`g_timeout_add()`用于设置周期性的回调函数,间隔时间由用户指定,单位为毫秒。当时间间隔过去...

    wing IDLE - Python

    Just a small tools for wing IDLE.

    Python 3.10 IDLE中文版及安装使用教程.zip

    Python 3.10 IDLE中文版是一款专为初学者设计的集成开发环境(IDE),尤其适合对中国语言有偏好的用户。IDLE是Python自带的标准轻量级开发工具,它提供了代码编辑、编译、执行等基本功能,是学习Python语法和实践...

    python IDLE shell 中文界面

    Python IDLE是Python的标准集成开发环境(IDE),它是一个轻量级、易上手的代码编辑器,尤其适合初学者。IDLE具有语法高亮、自动缩进、代码提示等功能,方便用户编写和调试Python代码。然而,默认情况下,IDLE的界面...

    Mongodb连接池JAVA

    MongoDB是一种流行的开源文档数据库系统,以其灵活性、可扩展性和高性能而受到开发者的青睐。在Java应用程序中,当处理大量并发请求时,有效地管理数据库连接是至关重要的。这就是MongoDB连接池的作用,它能帮助优化...

Global site tag (gtag.js) - Google Analytics