阿里Druid数据连接池引发的线上异常解决

 更新时间:2022年03月05日 14:31:28   作者:kl  
这篇文章主要为大家介绍了一次关于阿里Druid数据连接池引发的线上异常问题的解决方案,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步

前言

事件起因:项目使用了activiti工作流,系统是由老的spring mvc项目改造成的spring boot项目,数据库链接池从dbcp切换到druid,新系统上线后,同事多次系统隔一段时间后数据查询就很慢,基本出不来。

由此开始了线上bug排查之路。这个问题从一开始就模糊定位到数据库层面的问题,因为只有和数据相关的操作会很慢,其他服务不受影响,并且在中午休息时没有问题,在下午刚上班后不就出现。

过程一:定位工作流

首先第一反应是看日志:日志一切正常,并没有任何异常信息抛出,然后将日志级别调整到debug,发现了一些问题,中午休息时,用户没有操作的情况下,日志一直在输出jpa的连接信息,最后定位是工作流的异步执行器在轮询,因为在spring boot环境下spring.activiti.async-executor-activate=true默认是true的,如果不需要使用可以设置为false,改完后情况依旧

过程二:定位JPA的OpenEntityManagerInViewInterceptor

使用OpenEntityManagerInViewInterceptor后服务端在接收到一个请求的时候开启EntityManager,在请求结束的时候才去关闭这个EntityManager,所以在用户数多,并发高,操作耗时的情况下会造成数据连接不够用的情况,而我们的业务有这个特征。

在spring boot环境中,OpenEntityManagerInViewInterceptor默认是开启的,然而我们使用spring.jpa.open-in-view=false关闭后,问题依旧,不过比之前的间隔时间久一点了

过程三:定位Druid,真正的罪魁祸首

使用top定位到程序pid,然后使用jstack -l 2591 >>dump.out 拿到当前堆栈快照后发现如下

"http-nio-8080-exec-54" daemon prio=10 tid=0x0000000000e61000 nid=0xcc9 waiting on condition [0x00007f4a753d4000]
   java.lang.Thread.State: WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for  <0x00000007a143f230> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
	at com.alibaba.druid.pool.DruidDataSource.takeLast(DruidDataSource.java:1732)
	at com.alibaba.druid.pool.DruidDataSource.getConnectionInternal(DruidDataSource.java:1330)
	at com.alibaba.druid.pool.DruidDataSource.getConnectionDirect(DruidDataSource.java:1198)
	at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:4619)

所有的请求都被druid的获取连接操作阻塞了,最后看源码如下

因为数据链接没有释放,连接池中无可用连接,导致请求被阻塞了

到这里基本上就是真相了,最后换成spring boot自带的连接池tomcat jdbc后一切正常

后记:

定位到问题后,发现网上很多人遇到了连接泄露的情况,可见druid的官方issue,如https://github.com/alibaba/druid/issues/1160

不过druid也提供了相应的方案,如下

虽然官方说可能是应用自己导致连接未被释放导致连接泄露,但是为什么切换别家的连接池后就毛事都没有呢,元芳,你怎么看呢?

以上就是阿里Druid数据连接池引发的线上异常解决的详细内容,更多关于Druid数据连接池线上异常的资料请关注脚本之家其它相关文章!

相关文章

  • Java分层概念详解

    Java分层概念详解

    这篇文章主要介绍了Java分层概念详解,内容十分详细,在这里给大家分享下,需要的朋友可以参考。
    2017-09-09
  • SpringMVC事件监听ApplicationListener实例解析

    SpringMVC事件监听ApplicationListener实例解析

    这篇文章主要介绍了SpringMVC事件监听ApplicationListener实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • SpringBoot使用druid配置多数据源问题

    SpringBoot使用druid配置多数据源问题

    这篇文章主要介绍了SpringBoot使用druid配置多数据源问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • Mybatis延迟加载原理和延迟加载配置详解

    Mybatis延迟加载原理和延迟加载配置详解

    这篇文章主要介绍了Mybatis延迟加载原理和延迟加载配置详解,MyBatis中的延迟加载,也称为懒加载,是指在进行表的关联查询时,按照设置延迟规则推迟对关联对象的select查询,需要的朋友可以参考下
    2023-10-10
  • springboot jackson自定义序列化和反序列化实例

    springboot jackson自定义序列化和反序列化实例

    这篇文章主要介绍了spring boot jackson自定义序列化和反序列化实例,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • 利用Java代码写一个并行调用模板

    利用Java代码写一个并行调用模板

    这篇文章主要介绍了利用Java代码写一个并行调用模板,文章基于Java的相关内容展开写一个并行调用模板的详细介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-05-05
  • SpringBoot实现文件下载的限速功能

    SpringBoot实现文件下载的限速功能

    在SpringBoot项目中,实现文件下载的限速功能可以有效控制服务器带宽的占用,并防止单个用户消耗过多的资源,本文将通过具体的代码示例和详细的流程解释,介绍如何在SpringBoot项目中实现文件下载的限速功能,需要的朋友可以参考下
    2024-07-07
  • SpringBoot整合Elasticsearch7.2.0的实现方法

    SpringBoot整合Elasticsearch7.2.0的实现方法

    这篇文章主要介绍了SpringBoot整合Elasticsearch7.2.0的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • SpringCloud Eureka服务发现实现过程

    SpringCloud Eureka服务发现实现过程

    这篇文章主要介绍了SpringCloud Eureka服务发现实现过程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • 最通俗的白话讲解JDK源码中的ThreadLocal

    最通俗的白话讲解JDK源码中的ThreadLocal

    ThreadLocal是JDK包提供的,它提供线程本地变量,如果创建一乐ThreadLocal变量,那么访问这个变量的每个线程都会有这个变量的一个副本,在实际多线程操作的时候,操作的是自己本地内存中的变量,从而规避了线程安全问题,感兴趣的朋友快来看看吧
    2022-01-01

最新评论