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

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

应用报错,表象来看是连接池爆满了。

org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, pool exhausted
    at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:241) ~[spring-jdbc-3.2.2.RELEASE.jar:3.2.2.RELEASE]
    at com.alibaba.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:82) [dubbo-2.5.3.jar:2.5.3]
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [na:1.6.0_33]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [na:1.6.0_33]
    at java.lang.Thread.run(Thread.java:662) [na:1.6.0_33]
Caused by: org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, pool exhausted
    at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:103) ~[commons-dbcp.jar:1.2.1]
    at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:540) ~[commons-dbcp.jar:1.2.1]
    at com.eshore.crmpub.jdbc.datasource.MultiDataSource.getConnection(MultiDataSource.java:74) ~[crmpub-jdbc-1.0.jar:1.0]
    at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:203) ~[spring-jdbc-3.2.2.RELEASE.jar:3.2.2.RELEASE]
    ... 32 common frames omitted
Caused by: java.util.NoSuchElementException: Timeout waiting for idle object
    at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1174) ~[commons-pool-1.6.jar:1.6]
    at org.apache.commons.dbcp.AbandonedObjectPool.borrowObject(AbandonedObjectPool.java:74) ~[commons-dbcp.jar:1.2.1]
    at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:95) ~[commons-dbcp.jar:1.2.1]
    ... 35 common frames omitted

应用堆栈,几十条线程都阻塞到dbcp池的PoolableConnectionFactory.makeObject方法了,此方法在等待0x0000000709a638a0对象锁,但0x0000000709a638a0对象一直被其中一条线程执行PoolableConnectionFactory.makeObject时锁了,而且这条线程获取到锁后还阻塞住了,所以导致后面几十条线程都BLOCKED了。

"DubboServerHandler-132.121.95.136:28101-thread-300" daemon prio=10 tid=0x00007f02b4136800 nid=0x4954 waiting for monitor entry [0x00007f0286018000]
  java.lang.Thread.State: BLOCKED (on object monitor)
  at org.apache.commons.dbcp.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:290)
  - waiting to lock <0x0000000709a638a0> (a org.apache.commons.dbcp.PoolableConnectionFactory)
  at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1188)
  at org.apache.commons.dbcp.AbandonedObjectPool.borrowObject(AbandonedObjectPool.java:74)
  at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:95)
  at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:540)
  at com.eshore.crmpub.jdbc.datasource.MultiDataSource.getConnection(MultiDataSource.java:74)
  at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:203)
  at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:372)
  at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:417)
  at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:255)
  at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
  at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:80)
  at com.eshore.crm.service.common.pub.aspect.DataSourceRouteAspect.around(DataSourceRouteAspect.java:74)
  at sun.reflect.GeneratedMethodAccessor253.invoke(Unknown Source)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  at java.lang.reflect.Method.invoke(Method.java:597)
  at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621)
  at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:610)
  at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:65)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
  at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
  at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
  at com.eshore.crm.service.sysmgr.sca.impl.SysMgrServiceImpl$$EnhancerByCGLIB$$bfd71326.qryBulletinList(<generated>)
  at com.alibaba.dubbo.common.bytecode.Wrapper101.invokeMethod(Wrapper101.java)
  at com.alibaba.dubbo.rpc.proxy.javassist.JavassistProxyFactory$1.doInvoke(JavassistProxyFactory.java:46)
  at com.alibaba.dubbo.rpc.proxy.AbstractProxyInvoker.invoke(AbstractProxyInvoker.java:72)
  at com.alibaba.dubbo.rpc.protocol.InvokerWrapper.invoke(InvokerWrapper.java:53)
  at com.eshore.crmpub.sca.dubbo.filter.BaseFilter.invoke(BaseFilter.java:90)
  at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
  at com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol$1.reply(DubboProtocol.java:108)
  at com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.handleRequest(HeaderExchangeHandler.java:84)
  at com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.received(HeaderExchangeHandler.java:170)
  at com.alibaba.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:52)
  at com.alibaba.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:82)
  at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
  at java.lang.Thread.run(Thread.java:662)

  Locked ownable synchronizers:
  - <0x000000070a120f00> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
"DubboServerHandler-132.121.95.136:28101-thread-290" daemon prio=10 tid=0x00007f03203da800 nid=0x4948 runnable [0x00007f0286a22000]
  java.lang.Thread.State: RUNNABLE
  at java.net.SocketInputStream.socketRead0(Native Method)
  at java.net.SocketInputStream.read(SocketInputStream.java:129)
  at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:112)
  at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:159)
  at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:187)
  - locked <0x0000000715a9ce70> (a com.mysql.jdbc.util.ReadAheadInputStream)
  at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:3140)
  at com.mysql.jdbc.MysqlIO.readPacket(MysqlIO.java:597)
  at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1085)
  at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2494)
  at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2527)
  at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2309)
  - locked <0x00000007159d1898> (a com.mysql.jdbc.JDBC4Connection)
  at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:834)
  at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:46)
  at sun.reflect.GeneratedConstructorAccessor78.newInstance(Unknown Source)
  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
  at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
  at com.mysql.jdbc.Util.handleNewInstance(Util.java:408)
  at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:419)
  at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:344)
  at org.apache.commons.dbcp.DriverConnectionFactory.createConnection(DriverConnectionFactory.java:37)
  at org.apache.commons.dbcp.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:290)
  - locked <0x0000000709a638a0> (a org.apache.commons.dbcp.PoolableConnectionFactory)
  at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1188)
  at org.apache.commons.dbcp.AbandonedObjectPool.borrowObject(AbandonedObjectPool.java:74)
  at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:95)
  at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:540)
  at com.eshore.crmpub.jdbc.datasource.MultiDataSource.getConnection(MultiDataSource.java:74)
  at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:203)
  at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:372)
  at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:417)
  at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:255)
  at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
  at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:80)
  at com.eshore.crm.service.common.pub.aspect.DataSourceRouteAspect.around(DataSourceRouteAspect.java:74)
  at sun.reflect.GeneratedMethodAccessor253.invoke(Unknown Source)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  at java.lang.reflect.Method.invoke(Method.java:597)
  at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621)
  at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:610)
  at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:65)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
  at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
  at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
  at com.eshore.crm.service.cachemgr.sca.common.DictCacheServiceImpl$$EnhancerByCGLIB$$e27e8e25.getDict(<generated>)
  at com.alibaba.dubbo.common.bytecode.Wrapper93.invokeMethod(Wrapper93.java)
  at com.alibaba.dubbo.rpc.proxy.javassist.JavassistProxyFactory$1.doInvoke(JavassistProxyFactory.java:46)
  at com.alibaba.dubbo.rpc.proxy.AbstractProxyInvoker.invoke(AbstractProxyInvoker.java:72)
  at com.alibaba.dubbo.rpc.protocol.InvokerWrapper.invoke(InvokerWrapper.java:53)
  at com.eshore.crmpub.sca.dubbo.filter.BaseFilter.invoke(BaseFilter.java:90)
  at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
  at com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol$1.reply(DubboProtocol.java:108)
  at com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.handleRequest(HeaderExchangeHandler.java:84)
  at com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.received(HeaderExchangeHandler.java:170)
  at com.alibaba.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:52)
  at com.alibaba.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:82)
  at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
  at java.lang.Thread.run(Thread.java:662)

  Locked ownable synchronizers:
  - <0x000000070a0f9218> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)

可以看到其实获取锁的线程是阻塞在这里了,做mysql握手包的时候一直在等待读,阻塞在网络IO了。

 java.lang.Thread.State: RUNNABLE
  at java.net.SocketInputStream.socketRead0(Native Method)
  at java.net.SocketInputStream.read(SocketInputStream.java:129)
  at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:112)
  at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:159)
  at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:187)
  - locked <0x0000000715a9ce70> (a com.mysql.jdbc.util.ReadAheadInputStream)
  at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:3140)
  at com.mysql.jdbc.MysqlIO.readPacket(MysqlIO.java:597)
  at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1085)
  at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2494)
  at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2527)
  at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2309)

这个是dbcp1.x版本在创建新的连接对象时会把整个连接工厂类对象锁了,一旦创建过程中发生阻塞就会导致整个池都死掉。这个问题很大。

解决方案,升级dbcp2.x版本或tomcat jdbc或druid连接池,推荐druid连接池,功能强大自带监控。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • Java数据类型的规则

    数据类型的规则 选择合适的数据类型去存储,比如用来存储年龄,他的数值不可能超过200那么就用short存储,才浪费2个字节这样很节约.如果数值永远不大于100那么我们就会用byte来存储,如果这个数值不大于100非得用long长整型去存,就有点浪费了. 但是,现在不比10几年前了,以前的编程都是在微型机上做的.微型机上做编程他的资源非常的小,一个内存一个存储器都非常的小,所以那个时候必须在乎他的资源问题的使用,不能浪费里面的资源,不然资源越来越小. 现在的随便内存就是上G,服务器都上百G以上.所

  • java新特性之for循环最全的用法总结

    1. 增强for概述 增强for循环,也叫Foreach循环,用于数组和容器(集合类)的遍历.使用foreach循环遍历数组和集合元素时,无需获得数组和集合长度,无需根据索引来访问数组元素和集合元素,大大提高的效率,代码也简洁不少. 2. Oracle官网的解释 So when should you use the for-each loop? Any time you can. It really beautifies your code. Unfortunately, you cannot

  • Java中使用Jedis操作Redis的示例代码

    使用Java操作Redis需要jedis-2.1.0.jar,下载地址:jedis-2.1.0.jar 如果需要使用Redis连接池的话,还需commons-pool-1.5.4.jar,下载地址:commons-pool-1.5.4.jar package com.test; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.j

  • java配置dbcp连接池(数据库连接池)示例分享

    使用jar包:commons-dbcp-1.4.jar.commons-pool-1.6.jar.commons-logging-1.1.3.jar,另外还有数据库的jdbc驱动,适用java6及以上平台 连接池管理类 复制代码 代码如下: package cn.songxinqiang.samples.commonsdbcp.util; import java.sql.Connection;import java.sql.DatabaseMetaData;import java.sql.SQL

  • 零基础轻松学JavaScript闭包

    本文面向初学者,大神轻喷. 闭包是什么? 初学javascript的人,都会接触到一个东西叫做闭包,听起来感觉很高大上的.网上也有各种五花八门的解释,其实我个人感觉,没必要用太理论化的观念来看待闭包. 事实上,你每天都在用闭包,只是你不知道罢了. 比如: var cheese = '奶酪'; var test = function(){ alert(cheese); } OK,你已经写了一个闭包. 函数也是一个数据类型 变量 cheese 是在全局作用域中的一个变量,当你创建了一个 test 函

  • Java List转换成String数组几种实现方式详解

    Java List转换成String数组 实现代码: List<String> list = new ArrayList<String>(); list.add("a1"); list.add("a2"); String[] toBeStored = list.toArray(new String[list.size()]); for(String s : toBeStored) { System.out.println(s); } 或 Li

  • 基于java解析JSON的三种方式详解

    本文实例分析了基于java解析JSON的三种方式.分享给大家供大家参考,具体如下: 一.什么是JSON? JSON是一种取代XML的数据结构,和xml相比,它更小巧但描述能力却不差,由于它的小巧所以网络传输数据将减少更多流量从而加快速度. JSON就是一串字符串 只不过元素会使用特定的符号标注. {} 双括号表示对象 [] 中括号表示数组 "" 双引号内是属性或值 : 冒号表示后者是前者的值(这个值可以是字符串.数字.也可以是另一个数组或对象) 所以 {"name"

  • java启动线程的3种方式对比分析

    本文实例为大家分享了java启动线程的方法,供大家参考,具体内容如下 1.继承Thread public class java_thread extends Thread{ public static void main(String args[]) { (new java_thread()).run(); System.out.println("main thread run "); } public synchronized void run() { System.out.prin

  • JavaWeb Session失效时间设置方法

    session失效时间设置方法,具体方法如下所示: 一.java代码   <!--优先级是最高的--> request.getSession().setMaxInactiveInterval(1800);/*秒为单位,1800= 60*30 即30分种*/ 二.web.xml  <!--优先级是最低的--> <session-config> <!--分钟为单位--> <session-timeout>30</session-timeout&

  • java使用dbcp2数据库连接池

    在开发中中我们经常会使用到数据库连接池,比如dbcp数据库连接池,本章将讲解java连接dbcp数据库库连接池的简单使用. 开发工具myeclipse2014 1.首先创建一个web项目,我把项目名取名为testjdbc,需要带有web.xml的配置文件,进行servlet的配置,创建完成以后的项目结构如下: 2.创建包,我创建的包名是com.szkingdom.db 3.创建帮助类CastUtil,代码如下: package com.szkingdom.db; /** * Created by

  • JAVA中String类与StringBuffer类的区别

    在Java中有两种字符串的操作:String类和StringBuffer类(缓冲字符串处理类). 下面先简单的说一下两者的区别. String类和StringBuffer类都提供了相应的方法实现字符串的操作,但二者略有不同. (1) String类 该类一旦产生一个字符串,其对象就不可变.String类的内容和长度是固定的.如果程序需要获得字符串的信息需要调用系统提供的各种字符串操作方法实现.虽然通过各种系统方法可以对字符串施加操作,但这并不改变对象实例本身,而是生成一个新的实例.系统为Stri

  • 浅析Java中的继承与组合

    前言 Java是一个面向对象的语言.每一个学习过Java的人都知道,封装.继承.多态是面向对象的三个特征.每个人在刚刚学习继承的时候都会或多或少的有这样一个印象:继承可以帮助我实现类的复用.所以,很多开发人员在需要复用一些代码的时候会很自然的使用类的继承的方式,因为书上就是这么写的(老师就是这么教的).但是,其实这样做是不对的.长期大量的使用继承会给代码带来很高的维护成本. 其实我第一次学习java 的时候根本没有听说过组合这个名词,老师也更没有讲解过,我一直以为是我自己落掉了什么知识点,其实不

随机推荐