Java技术栈
www.javastack.cn
优秀的Java技术公众号
最近某个应用程序老是卡,需要重启才能解决问题,导致被各种投诉,排查问题是 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)
...
这个配置项虽然可用于排查连接池释放问题,但生产环境小心使用,如果有的业务执行事务的时间比较长,会被误回收,小心引发另外一个血案。
END
学习资料:
分享一份最新 Java 架构师学习资料
最近热文:
1、Tomcat 爆出高危漏洞!
2、HTTP连接选HttpClient还是OkHttp?
3、飞机上用的是什么操作系统?
4、为啥老外偏爱 Hibernate/JPA 呢?
5、程序员接私活,怎样防止做完不给钱?
6、Git 高级用法,喜欢就拿去用!
7、7 种 JVM 垃圾收集器,看完我跪了。
8、分享 14 个 Spring MVC 顶级技巧!
9、图文并茂,带你掌握 JVM 垃圾回收!
10、干掉PostMan!IDEA这款插件太实用了…
短视频:
1、Java 24 年发展史,辉煌的 24 年!
2、互联网工作生存指南,太真实了!
3、Java 8 中的永久代去哪了?
4、做了几年Java,还不知道什么是守护线程?
5、一图搞懂 Java 中的异常分类!
公众号干货实在太多了,扫码关注Java技术栈公众号看更多。
点击「阅读原文」带你飞~