druid 数据库查询间歇性阻塞15分钟

druid 数据库查询间歇性阻塞15分钟

问题描述

在预发布环境测试发现一个奇怪的问题,一开始是一个定时任务执行很慢,由于网络隔离不方便远程调试,选择在每个可能耗时的步骤前后打印详细日志,找出耗时原因。然后在查看日志的时候发现,问题出在一个查询sql,这个查询足足等待了15分钟,但是并不是每次都会这样,并且只要出现这个情况基本就会等待15分钟。

问题分析

检测代码,该查询sql是一个很简单的查询,并且查询的是一个标记表,其中只有几十条数据,所以可以排除数据库慢查询的问题,而且由于是偶发性的,在检查对应的代码后没有发现问题,因此怀疑是否可能是在那一时刻cpu负载过高导致,以前在跑spark任务的时候经常会遇见GC overhead limt exceed的问题,当jvm内存不够时很可能会导致cpu被gc线程占满,这样是会导致用户线程长时间卡顿的。所以使用jstat查看了服务启动以来gc的大致情况,发现服务自启动以来gc所用时间远远不足到15分钟,并且堆内存各个区域占用表现正常,因此基本可以排除gc的问题。
然后又思考其他可能,既然是sql,那还是回到数据库本身考虑,项目使用的是oracle数据库,怀疑被阻塞的那个sql是否被其他事物阻塞了或者表被锁住了,然后去查看V L O C K 和 V LOCK和V LOCKVSESSION表,发现也被没有这种情况。(实际上被阻塞的是一个 select * from table的语句,没有声明加锁,讲道理即使存在其他事物锁定该表,这个查询应该也不会被阻塞)因此当时并没有结论。

问题再现

问题被搁置2天后,新的问题又出现了,这次的表现是,前端一个查询界面,一开始是OK的,放置一段时间后,再点击查询,迟迟没有响应。而且这问题在开发环境和测试环境没有出现,由于使用了nginx代理,首先排查nginx各项参数和测试环境是否有出入。
然后继续日志埋点,分析日志发现,出现了同样的问题,也是被一个select语句阻塞了15分钟。这下就很奇怪了,这个15分钟到底是哪来的,每次都不多不少15分钟,项目使用的是druid,排查各项参数没有任何可以和15分钟关联的,在程序本身和数据库表这2个因素没有找到问题,选择面向百度编程,无奈之下搜索15分钟关键字,还真找到了类似的情况,该文章标题是《 keepAlive解决druid空闲连接socket timeout 15分钟 》,按照文章的意思,配置了spring.datasource.druid.keep-alive=true参数后,果然就没出现阻塞的情况了。并且在debug日志里找到了一个异常 oracle关闭的连接,结合文章所述,这个异常大概率就是druid检测连接是否有效时执行语句超时导致的。查看druid测试连接的源码方法,在DruidAbstractDataSource 中的testConnectionInternal方法,可知如果测试连接的sql(可配置,oracle一般为select 1 from dual)执行异常,在finally语句中返回false从而销毁该连接重新获取新的连接。

总结

遇到问题不要慌,先晾他个两三天
文中提到的文章连接为 : link

  • 25
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值