4

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

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

然而,根据 c3p0 日志的分析,死锁检测线程的运行频率超过了 30 分钟。日志的相关部分附后。令人惊讶的是,频率并不统一。

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

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

4

2 回答 2

3

maxAdministrativeTaskTime不影响线程池的死锁检测器;它只是限制在池尝试执行单个任务之前允许执行的长度interrupt()。一种(hackish!,丑陋!,不建议!)尝试避免明显死锁的方法是将其设置为 SHORT 间隔,以便慢速任务被中断而不是挂起太久以至于池决定它被卡住。请在此处查看一些讨论。

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

值得了解死锁检测器的作用。c3p0 维护一个线程池,numHelperThreads很大。死锁检测器定期记录池中所有线程正在运行的任务,然后休眠一段时间,然后再次检查。如果没有任务完成,即活动任务与上次检查期间完全相同,则宣布死锁。c3p0 期望某个任务完成的时间间隔是 10 秒,目前无法配置。它可以是可配置的。

您可能会发布一些您看到的表观死锁的示例。c3p0 打印大量信息以帮助您了解可能挂起的内容。

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

  1. 您观察到的死锁与连接获取有关吗?如果是这样,如果您还没有,请升级到 c3p0-0.9.2.1 或最新的 0.9.5 预发行版。

  2. 您是否尝试过随着numHelperThreads负载的增加而增加?如果某些任务非常慢,c3p0 不会声明死锁,除非所有线程都被慢速任务阻塞。如果有足够多的线程来执行更灵活的任务,您将不会看到死锁。

我希望这有帮助!

于 2013-06-27T06:35:14.797 回答
1

我无法解释,但是 1000 个连接是相当多的,您的 c3p0 配置是否反映了如此高的连接数?我的经验是默认设置适用于较少的连接数。我建议阅读c3po 文档,尤其是“其他数据源配置”下的部分。

于 2013-06-26T18:59:58.080 回答