HikariPool连接超时解决方案
问题描述
描述:线上隔一段时间会数据库连接池超时
默认连接超时时间是3000ms,所以分析原因有可能是连接泄漏(在从池中借用之后连接没有关闭)。在定位问题之前先看下hikari配置信息:
Hikari配置说明:
为了更精确的定位此问题,我加大了连接,并且设置了leakDetectionThreshold属性
环境配置
构建镜像
因为线上使用docker部署微服务环境,所以使用docker部署环境
查看镜像:
运行容器
注意在容器里使用jmap 命令打印堆栈会报错了!“Can’t attach to the process: ptrace(PTRACE_ATTACH, …) failed for 1: 不允许的操作”
[解决方法]
https://blog.csdn.net/weixin_43103748/article/details/104053104
我选择第二种方法即运行容器使用 --cap-add 明确添加指定功能解决:
docker run --cap-add=SYS_PTRACE ...
问题定位
查看该容器的进程
先进入容器:
docker exec -it sj-eto-api /bin/bash
再查看进程
jps
用top命令发现cpu占比不高
用jstat查看发现新老年代。发现新老年代还有足够的空间
重新定位日志,发现每隔1小时,使用Hikari CP检测到明显的连接泄漏。发现是代码里定时任务导致数据库连接泄漏
参照:
https://www.jianshu.com/p/5d1ab3d01761?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation
结合我们的业务发现,此处确实是使用连接的时间超出了leakDetectionThreshold毫秒,是因为执行了慢 sql,同时慢 sql 耗尽了连接池的连接,导致新线程获取连接超时,又导致了获取连接超时的报错。
所以定位代码发现使用sqlSession去建立数据库连接,但是没有关闭连接,定时1个小时去创建,默认连接数是10,所以很快就连接数不够。
所以解决方法在finally里加了close方法