内容提要
文章讨论了使用 Alibaba Druid 数据源时应用程序无响应的问题,主要由于线程在等待 `com.alibaba.druid.pool.DruidDataSource.takeLast()` 方法导致死锁。通过配置 `maxWait` 参数可以解决此问题,避免程序无限等待连接。默认情况下,`maxWait` 为 -1,表示无限等待。更新版本中对此进行了修正。
延伸解读
maxWait 默认值 -1 的风险
Druid 的 maxWait 参数默认值为 -1,表示从连接池获取连接时无限等待。当连接池耗尽时,线程会一直阻塞在 takeLast() 方法上,导致应用无响应且无错误日志。这种设计在连接泄漏或高并发场景下极易引发故障,因此生产环境应显式设置 maxWait 为一个合理值,避免无限等待。
死锁触发条件与堆栈特征
死锁发生在 maxWait <= 0 时,Druid 调用 takeLast() 而非 pollLast()。takeLast() 基于 AQS 实现,当无可用连接时线程进入 WAITING 状态。若连接池中的连接被长时间占用或泄漏,等待线程将无法被唤醒,形成死锁。通过堆栈可观察到大量线程阻塞在 takeLast() 方法,这是诊断该问题的关键线索。
版本差异与修复情况
文章指出在 Druid 1.2.17 版本中,maxWait 默认 -1 会导致无限等待。2024 年 1 月 23 日的提交(6ec6c006)修改了相关代码,可能改变了默认行为或增加了保护机制。使用旧版本的用户需自行配置 maxWait,而新版本用户可关注该提交的具体改动,以评估是否仍需显式设置。
Q&A
为什么我的应用程序会无响应?
应用程序无响应主要是因为线程在等待 `com.alibaba.druid.pool.DruidDataSource.takeLast()` 方法导致死锁。
如何解决 Druid 数据库连接池的死锁问题?
通过在配置文件中设置 `maxWait` 参数,可以避免程序无限等待连接,从而解决死锁问题。
maxWait 参数的默认值是什么?
默认情况下,`maxWait` 的值为 -1,表示无限等待。
如何配置 maxWait 参数以避免程序无响应?
在配置文件中增加对 `maxWait` 的配置,设置一个正值即可避免程序无响应。
Druid 数据库连接池的最新版本是否修复了死锁问题?
是的,最新版本中对死锁问题进行了修正,代码已更新。
死锁发生时线程的状态是什么?
死锁发生时,大部分线程的状态为 WAITING,表示它们在等待连接。