c3p0存在严重bug
开发的系统使用了Spring JdbcTemplate + c3p0组合,在做性能测试的时候出现了严重的性能问题。40的并发访问,开始的时候系统正常,等过了几分钟后,应用程序不能访问了。停止40并发的压力 后,过1分钟左右又可以正常访问应用程序了,很迷茫。后台log文件有警告信息:
2011-11-01 13:48:39,378 [com.mchange.v2.async.ThreadPoolAsynchronousRunner:435]
-[WARN] com[email protected]4ec5571b
-- APPARENT DEADLOCK!!!
Complete Status: [num_managed_threads: 10, num_active: 10; activeTasks: [email protected]03 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#6), [email protected]81 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#9), [email protected]b8 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#7),
把c3p0换为DBCP后,系统可以正常进行性能测试,访问正常,判定c3p0存在bug。
上网查找资料,发现很多人也遇到了"APPARENT DEADLOCK"的问题
http://www.iteye.com/topic/71051
http://www.iteye.com/topic/22160
http://www.iteye.com/topic/87313
http://www.iteye.com/topic/429677
https://forum.hibernate.org/viewtopic.php?f=1&t=947246&sid=ad2b8cc3213c9dac834d81b55bbf6291
没有找到解决答案,但是基本了解了c3p0的运行原理。c3p0在从连接池中获取和返回连接的时候,采用了异步的处理方式,使用一个线程池来异步的 把返回关闭了(没有真正关闭)的连接放入连接池中。这样就意味着,我们在调用了从c3p0获得的连接的close方法时,不是立即放回池中的,而是放入一 个事件队列中等待c3p0内部的线程池顺序的处理。
c3p0中有2个参数和内部的连接池有关,分别是:
其含义的官方描述在:
http://www.mchange.com/projects/c3p0/index.html
其中通过查看c3p0的源码,可以看出那些功能是需要内部线程池处理的:
expandPool -- 在扩大池中连接的时候,如管理的连接从20扩大到40个
shrinkPool -- 在缩小连接池的时候,这个过程需要真正关闭一些连接
doCheckinManaged -- 把连接返回给连接池
checkIdleResources -- 定时检查池中的连接
遇到上面的“APPARENT DEADLOCK”警告就是由于c3p0内部线程池的所有线程都被挂起而造成的,因此官方文档说把仔细查看log日志,会发现都是那些任务占据了宝贵的线程:
[com.mchange.v2.async.ThreadPoolAsynchronousRunner:435]-[WARN] com[email protected]4ec5571b
-- APPARENT DEADLOCK!!! Complete Status: [num_managed_threads: 10, num_active: 10;
activeTasks:
[email protected]03 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#6),
[email protected]81 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#9),
[email protected]b8 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#7),
[email protected]0 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#4),
[email protected]76 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0),
[email protected]09 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2),
[email protected]7a (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#3),
[email protected]84 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1),
[email protected]50 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#5),
[email protected]97 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#8);
pendingTasks:
[email protected],
[email protected]2e,
[email protected]2,
[email protected],
[email protected]53,
[email protected]27,
[email protected],
[email protected]59,
[email protected],
可以看到AcquireTask占用了内部线程池的所有线程,没有线程可以来执行BasicResourcePool$6对应的任务,而这个任务的作用就是把池外使用完的连接放回池内的,c3p0被挂起了。
我的解决方法是用单独的线程来处理“归还”连接的任务,因为这个任务的优先级最高,而且耗费的时间很短。
上传我修改后的 c3p0 jar包,只改了一个文件:BasicResourcePool
上一篇: 设计模式-单实例模式
下一篇: 【设计模式】单实例模式
推荐阅读
-
解析Tomcat 6、7在EL表达式解析时存在的一个Bug
-
微软承认Win10存在严重NTFS漏洞:解压缩包等会损坏硬盘
-
Win10累积更新KB3213986正常升级但存在已知BUG解决方法
-
Win10累积更新KB3213986正常升级但存在已知BUG解决方法
-
IE存在严重漏洞:微软停止Windows 7等系统安全更新
-
更新补丁翻车:Win10文件资源管理器Bug依然存在
-
微软发布KB4010250补丁 紧急修复Win10严重Bug
-
苹果新款macOS存在严重Bug 传输大文件时系统崩溃
-
win10严重Bug修复补丁KB4010250下载地址 64位/32位
-
蓝牙被爆存在严重缺陷:手机用户遭殃 秒被黑