某个系统上线后出现连接池耗尽,如何一步步排查。可能还需要引用知识库中的具体配置示例,比如HikariCP的配置参数,或者Druid的监控方法。
遇到了线上连接池耗尽的问题,想要了解如何快速定位和解决。
某核心业务系统上线后,用户反馈访问缓慢,部分接口出现超时甚至报错。通过监控平台查看,发现服务端异常日志中频繁出现如下错误:
text Caused by: java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30000ms.
这表明 数据库连接池资源已经耗尽,请求无法获取数据库连接,导致服务不可用。
接口响应超时、数据库连接超时异常(如 SQLTransientConnectionException)。
监控指标:
HikariCP 配置示例:
yaml spring: datasource: hikari: #最小空闲连接,默认值10 minimum-idle: 5 # 连接池大小及超时等配置 maximum-pool-size: 20 # 空闲连接超时时间, idle-timeout: 30000 # 连接超时时间 connection-timeout: 30000 pool-name: pool-1
监控工具:
关键指标:
代码审查重点:
问题代码:
java @Resource private PlatformTransactionManager transactionManager; public void queryData() { TransactionStatus transaction = transactionManager.getTransaction(new DefaultTransactionDefinition()); // 代码异常,导致没有提交与回滚 .... try { } catch (Exception e) { transactionManager.rollback(transaction); } finally { if (Objects.nonNull(transaction) && transaction.isNewTransaction() && !transaction.isCompleted()) { transactionManager.commit(transaction); } } }
MySQL 慢查询日志:
sql SHOW VARIABLES LIKE 'slow_query_log'; SET GLOBAL slow_query_log = 'ON'; SET GLOBAL long_query_time = 1; -- 执行时间超过 1 秒的查询记录日志
工具辅助:
示例命令:
sh jstack <pid> | grep "HikariPool" -A 20 # 查找连接池相关线程
现象: 请求卡死无响应,线程数居高不下,CPU 可能不高但吞吐为零或极低。
jstack 分析线程状态:
死锁检测: jstack 输出末尾通常会报告 Found one Java-level deadlock,列出死锁线程和锁信息。分析相关代码的同步逻辑。
检查锁使用: 是否过度使用 synchronized 或粗粒度锁?是否该用并发集合 (ConcurrentHashMap) 或更高级的锁 (StampedLock, ReadWriteLock)?
资源等待: 数据库连接池耗尽、HTTP 连接池耗尽、文件句柄耗尽等也会导致线程阻塞。检查相关资源池状态。
注意
数据库连接池耗尽、HTTP 连接池耗尽、文件句柄耗尽等也会导致线程阻塞,需要检查相关资源池状态。
DB 连接池耗尽问题的核心在于 连接资源管理不当,需从配置、代码、数据库优化和监控四个方面综合解决。
本文作者:张豪
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!