BasicDataSource分配8个连接后无法获取更多,Tomcat锁死如何排查?
排查步骤
1. 验证DBCP2连接池核心配置
- 检查
maxTotal(最大总连接数)、maxIdle、minIdle参数是否被错误设置为8。注意DBCP2与旧版DBCP参数名不同,新版用maxTotal而非maxActive,确认配置文件(如Tomcat的context.xml)中参数拼写、大小写无误。 - 排查代码层面是否硬编码覆盖配置,例如是否存在
basicDataSource.setMaxTotal(8)这类语句。 - 确认配置是否生效:可以在代码中打印
basicDataSource.getMaxTotal()的值,验证实际生效的参数。
2. 排查连接泄漏问题
- 确认测试函数中连接是否被正确释放:检查是否所有连接都在
try-with-resources块中使用,或在finally块中执行了close()操作,避免遗漏释放。 - 开启DBCP2泄漏检测:添加配置
logAbandoned=true、removeAbandonedOnBorrow=true、removeAbandonedTimeout=60,连接泄漏时会打印堆栈日志,定位未释放连接的代码位置。 - 查看Tomcat日志,是否存在连接被标记为
abandoned的记录。
3. 检查MySQL连接状态与配置
- 执行
SHOW PROCESSLIST;命令,查看MySQL当前连接数及状态:测试第9个连接请求时,确认是否仅8个连接来自Tomcat,有无其他进程占用连接。 - 验证MySQL连接有效性检测:配置DBCP2的
testOnBorrow=true和validationQuery="SELECT 1",确保连接池获取的是可用连接,避免因MySQL主动关闭连接(如wait_timeout超时)导致无效连接占满池。
4. 检查Linux系统资源限制
- 查看Tomcat进程的文件句柄限制:每个数据库连接会占用一个文件句柄,执行
ulimit -n(需切换到Tomcat运行用户),若限制过低(如小于64)会限制连接数。可在Tomcat启动脚本中添加ulimit -n 4096提升限制。
5. 排查依赖冲突与版本兼容性
- 确认DBCP2版本与Tomcat 8兼容:避免使用与Tomcat自带连接池jar冲突的版本,检查classpath中是否存在多版本的DBCP或MySQL驱动jar包。
6. 分析线程转储
- Tomcat锁死时,执行
jstack <Tomcat进程ID>获取线程转储,查看等待连接的线程堆栈:若线程卡在GenericObjectPool的锁上等待,说明连接池无可用连接且无法创建新连接,需回到连接池配置或泄漏问题排查。
内容的提问来源于stack exchange,提问作者Flarosa
相关产品推荐
相关产品推荐

