这周有个应用的一个实例出现了没有响应,庆幸运维那边在重启前做了线程和内存的 dump 。
线程 dump 文件打开一看,竟然4万多行。。后来发现同事用一个可视化工具来分析线程栈,我也把这个工具加入工具箱:IBM Thread and Monitor Dump Analyzer for Java
可以按线程名词、状态、方法栈的深度来进行排序。
下面说说这次踩的坑。
从线程栈来看,200个 tomcat 线程都在等待获取数据库连接,首先怀疑是不是数据库连接泄漏。
全局搜了代码,发现直接使用 Connection 的地方都不存在泄漏的。
想起这个 SpringBoot druid 踩坑笔记,怀疑是不是配置有问题,本地验证了下,配置是没问题的,连接池最大个数 50 个。
因为之前也听过 Druid 存在死锁的故事,网上搜到了这篇文章 【问题经验】记一次Dubbo线程耗尽的问题-druid数据库连接池突发性能
核对线程栈发现确实存在类似的情况:Druid 专门负责创建连接的线程在创建好连接准备添加到池里时、阻塞在获取锁上,这个锁在线程栈上 dump 文件上并没有找到被哪个线程持有,通过内存 dump 发现这个锁也确实没有被人持有,妥妥的的一个并发问题的 bug 。
因为公司网络隔离,没有截取保存当时分析的内容。
Druid 的版本是 1.0.15 。
欢迎关注我的微信公众号: coderbee笔记 。