2026-05-24 10:04:01
答案:通过启用Druid连接池的强制回收功能(removeAbandoned)并配置超时时间(removeAbandonedTimeoutMillis)及日志记录(logAbandoned),成功定位并解决了连接泄露问题。但需注意生产环境谨慎使用,避免误回收长时间运行的事务。
问题分析启用连接泄露检测配置:
removeAbandoned=true:开启强制回收未释放的连接。
removeAbandonedTimeoutMillis=600000:设置超时时间为600秒(10分钟),超时后强制回收。
logAbandoned=true:记录泄露连接的堆栈信息,辅助定位问题代码。
配置效果:
Druid在连接池初始化时启动后台线程(createAndStartDestroyThread),定期检查超时未归还的连接。
超时连接被强制回收,同时打印堆栈日志(如示例中的owner thread: https-jsse-nio-4443-exec-9),直接指向未关闭连接的代码位置。
定位问题代码:
根据日志中的堆栈信息(如DruidDataSource.getConnectionDirect和AbstractRoutingDataSource.getConnection),可追溯到Spring事务管理或手动获取连接后未关闭的代码段。
生产环境风险:
若业务事务执行时间较长(超过removeAbandonedTimeoutMillis),可能被误回收,导致数据不一致。
建议:生产环境谨慎启用,或根据业务调整超时时间(如延长至30分钟)。
替代方案:
代码审查:全局检查Connection、Statement、ResultSet是否在finally块中关闭。
工具辅助:使用Arthas等工具动态追踪连接获取/释放流程。
通过Druid的泄露检测配置,快速定位了连接未释放的代码位置,解决了连接池耗尽问题。但需权衡功能与风险,避免在生产环境中误伤正常长事务。建议结合代码规范和监控工具,从根本上杜绝连接泄露。