2013-06-26 81 views
4

我们使用Hibernate和c3p0连接池库。到目前为止,直到最近,当我们决定将maxPoolSize增加到1000并对我们的应用程序进行大量的压力测试时,这种组合效果很好。我们的应用程序的峰值负载导致数据库响应非常缓慢,因此c3p0的死锁检测器一次又一次地吐出APPARENT DEADLOCK警告。c3p0死锁检测 - 线程运行太频繁

基于c3p0文档,假设死锁检测每30分钟发生一次(代码表示死锁检测频率是maxAdministrativeTaskTime的三倍),我们将maxAdministrativeTaskTime更改为10分钟。

但是,在分析c3p0日志时,死锁检测线程运行频率超过30分钟。日志的相关部分已附加。令人惊讶的是频率不统一​​。

Line 573745: [Timer-2] 2013-06-26 04:47:52,492 WARN [null] com[email protected]662cee3b -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! 
Line 573746: [Timer-2] 2013-06-26 04:47:52,512 WARN [null] com[email protected]662cee3b -- APPARENT DEADLOCK!!! Complete Status: 
Line 574292: [Timer-2] 2013-06-26 04:49:12,493 WARN [null] com[email protected]662cee3b -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! 
Line 574293: [Timer-2] 2013-06-26 04:49:12,513 WARN [null] com[email protected]662cee3b -- APPARENT DEADLOCK!!! Complete Status: 
Line 575004: [Timer-2] 2013-06-26 04:50:32,494 WARN [null] com[email protected]662cee3b -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! 
Line 575005: [Timer-2] 2013-06-26 04:50:32,511 WARN [null] com[email protected]662cee3b -- APPARENT DEADLOCK!!! Complete Status: 
Line 576062: [Timer-2] 2013-06-26 04:51:52,495 WARN [null] com[email protected]662cee3b -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! 
Line 576063: [Timer-2] 2013-06-26 04:51:52,536 WARN [null] com[email protected]662cee3b -- APPARENT DEADLOCK!!! Complete Status: 
Line 576720: [Timer-2] 2013-06-26 04:53:12,496 WARN [null] com.mchange.v2.async.ThreadPoolAsynchrono[email protected] -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! 
Line 576721: [Timer-2] 2013-06-26 04:53:12,516 WARN [null] com[email protected]662cee3b -- APPARENT DEADLOCK!!! Complete Status: 
Line 594087: [Timer-2] 2013-06-26 04:55:52,550 WARN [null] com[email protected]662cee3b -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! 
Line 594088: [Timer-2] 2013-06-26 04:55:52,569 WARN [null] com[email protected]662cee3b -- APPARENT DEADLOCK!!! Complete Status: 
Line 594753: [Timer-2] 2013-06-26 04:57:12,550 WARN [null] com[email protected]662cee3b -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! 
Line 594754: [Timer-2] 2013-06-26 04:57:12,572 WARN [null] com[email protected]662cee3b -- APPARENT DEADLOCK!!! Complete Status: 
Line 595624: [Timer-2] 2013-06-26 04:58:32,552 WARN [null] com[email protected]662cee3b -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! 
Line 595625: [Timer-2] 2013-06-26 04:58:32,570 WARN [null] com[email protected]662cee3b -- APPARENT DEADLOCK!!! Complete Status: 
Line 596416: [Timer-2] 2013-06-26 04:59:52,552 WARN [null] com[email protected]662cee3b -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! 
Line 596417: [Timer-2] 2013-06-26 04:59:52,572 WARN [null] com[email protected]662cee3b -- APPARENT DEADLOCK!!! Complete Status: 
Line 611011: [Timer-2] 2013-06-26 05:02:22,556 WARN [null] com[email protected]662cee3b -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! 
Line 611012: [Timer-2] 2013-06-26 05:02:22,577 WARN [null] com[email protected]662cee3b -- APPARENT DEADLOCK!!! Complete Status: 

有人可以解释这个异常吗?

+0

好的。所以对于我下面的初步答案感到抱歉,这并不好。我纠正了错误的部分。现在看起来更仔细,有很多这是怪异的。您不仅经常意外地看到死锁,而且您看到的死锁根本不应该是死锁,“完整状态:”是空的。应该有线程池中任务的转储和它们的堆栈跟踪。没有。 (你的记录器截断多行日志项目?) –

回答

1

我无法解释它,但1000个连接相当多,您的c3p0配置是否反映了这么多的连接?我的经验是,默认设置适合较少数量的连接。 我建议阅读c3po documentation,尤其是“其他数据源配置”下的部分。

2

maxAdministrativeTaskTime不影响线程池的死锁检测器;它只限于在池试图对其执行interrupt()之前允许执行单个任务的时间长度。一个(hackish !,丑陋!,不建议!)试图避免APPARENT DEADLOCKs的方法是将其设置为SHORT间隔,以便缓慢的任务会被中断,而不是挂起很长时间,以致池会决定它被卡住。请参阅一些讨论here

感谢提问者(通过电子邮件),我仔细检查了我自己的%$^* &!代码,并且死锁检测间隔maxAdministrativeTaskTime影响。如问题所示,它应该是3 × maxAdministrativeTaskTime。所以神秘加深了。

值得了解死锁检测器的功能。 c3p0维护一个线程池,numHelperThreads大。死锁检测器会定期记录池中线程正在运行的所有任务,然后睡眠一段时间,然后再次检查。如果没有任何的任务已完成,即活动任务保持与上次检查期间完全相同,则声明死锁。 c3p0期望某个任务完成的时间间隔为10秒,现在不可配置。它可以被配置。

你可能会发表一些你看到的APPARENT DEADLOCK的例子。 c3p0会打印大量信息,以帮助您了解可能挂起的内容。

这里有两个建议,以减少非常重负载下表观死锁:

  1. 是你观察相关连接acqusistion死锁?如果是这样,如果你还没有,请升级到c3p0-0.9.2.1或最新的0.9.5预发布。

  2. 您是否尝试增加numHelperThreads,因为您已经放大了负载?如果某些任务非常慢,c3p0将不会声明死锁,除非所有线程都被慢速任务阻塞。如果有足够的线程以便更灵活的任务仍然执行,则不会看到死锁。

我希望这有助于!