一次 Druid 连接池泄露引发的血案

简介: 最近某个应用程序老是卡,需要重启才能解决问题,导致被各种投诉,排查问题是Druid 连接池泄露引发的血案。。

最近某个应用程序老是卡,需要重启才能解决问题,导致被各种投诉,排查问题是Druid 连接池泄露引发的血案。。

异常日志如下:

ERROR - com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 60000, active 50, maxActive 50, creating 0
    at com.alibaba.druid.pool.DruidDataSource.getConnectionInternal(DruidDataSource.java:1512)
    at com.alibaba.druid.pool.DruidDataSource.getConnectionDirect(DruidDataSource.java:1255)
    at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:5007)
    at com.alibaba.druid.filter.stat.StatFilter.dataSource_getConnection(StatFilter.java:680)
    at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:5003)
    at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:1233)
    at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:1225)
    at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:90)

连接池中的连接数量已经到达最大值了,到了 60 秒还不能创建连接就超时报错了。

问题很明显,肯定是应用程序哪里用了连接但没有释放,全局排查代码又比较艰难,加了三个 Druid 连接池配置项,最终定位并解决了问题。

添加以下配置:

这就是连接泄露配置项,如果连接长时间不归还,removeAbandoned 打开状态,超过
removeAbandonedTimeoutMillis 设置的超时时间,将会强制回收连接。

连接池初始化时会启动一个线程,用于检查并回收连接。

参考源码:

com.alibaba.druid.pool.DruidDataSource#createAndStartDestroyThread

当 logAbandoned 打开状态时,关闭连接同时会记录当时的堆栈日志,可用于定位到哪些代码打开了连接没关闭。

abandon connection, owner thread: https-jsse-nio-4443-exec-9, connected at : 1573521883837, open stackTrace
    at java.lang.Thread.getStackTrace(Thread.java:1589)
    at com.alibaba.druid.pool.DruidDataSource.getConnectionDirect(DruidDataSource.java:1305)
    at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:4619)
    at com.alibaba.druid.filter.stat.StatFilter.dataSource_getConnection(StatFilter.java:680)
    at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:4615)
    at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:1225)
    at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:1217)
    at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:90)
    at org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource.getConnection(AbstractRoutingDataSource.java:162)
    ...

这个配置项虽然可用于排查连接池释放问题,但生产环境小心使用,如果有的业务执行事务的时间比较长,会被误回收,小心引发另外一个血案。

本文就是愿天堂没有BUG给大家分享的内容,大家有收获的话可以分享下,想学习更多的话可以到微信公众号里找我,我等你哦。

相关文章
|
9月前
|
Oracle 关系型数据库 数据库
【赵渝强老师】Oracle数据库的闪回查询
本文介绍了Oracle数据库的闪回查询(Flashback Query)功能及其实际应用。闪回查询通过`AS OF`子句,结合时间戳或SCN号,可查询历史数据状态,帮助分析数据差异。文中通过具体示例演示了如何使用闪回查询:创建测试表、记录当前SCN号、更新数据并提交事务,最后通过闪回查询获取历史数据。附带的视频和代码块详细展示了操作步骤与结果。
390 4
|
12月前
|
存储 Java Linux
【Maven】——基础入门,插件安装、配置和简单使用,Maven如何设置国内源
Maven插件安装,Maven项目构建,依赖管理,Haven Help插件,Maven仓库,Maven如何设置国内源
|
11月前
|
Java 程序员 开发者
面试官最爱的面试题:wait() 和 notify() 为什么需要同步?
大家好,我是小米。今天来探讨一个常见的Java面试题:为什么线程通信的 `wait()`、`notify()` 和 `notifyAll()` 方法被定义在 Object 类里,且必须在同步方法或同步块中调用?通过小明和小红的工作场景,我们理解了这些方法的核心思想——线程间的协调与通信。它们依赖于对象锁,确保线程按预期顺序执行,避免资源争抢和死锁。掌握这些知识点,能帮助你更好地应对多线程相关的面试问题。如果你对线程同步等话题感兴趣,欢迎继续交流。
182 12
|
机器学习/深度学习 人工智能 自然语言处理
AI战略丨物流 AI 新变化,用大模型定义
物流企业在大模型上纷纷主动探索,也在推动物流行业实现智能化加速。
|
弹性计算 人工智能 供应链
云服务器 ECS产品使用问题之端口已加入安全组,但是端口不通,同时服务器已关闭防火墙,是什么导致的
云服务器ECS(Elastic Compute Service)是各大云服务商阿里云提供的一种基础云计算服务,它允许用户租用云端计算资源来部署和运行各种应用程序。以下是一个关于如何使用ECS产品的综合指南。
|
SQL 安全 关系型数据库
MySQL数据库中的增删查改(MySQL最核心,工作中最常用的部分)
MySQL数据库中的增删查改(MySQL最核心,工作中最常用的部分)
1401 0
|
SQL 关系型数据库 MySQL
问题1:Navicat连接不上mysql8的简单解决办法
问题1:Navicat连接不上mysql8的简单解决办法
2486 2
|
数据采集 监控 搜索推荐
ERP系统中的财务指标与绩效评估解析
【7月更文挑战第25天】 ERP系统中的财务指标与绩效评估解析
648 0
|
Windows
Windows 程序自启动实现方法详解
Windows 程序自启动实现方法详解
454 0