首页 > 其他分享 >记一次 Druid 超时配置的问题 → 引发对 Druid 时间配置项的探究

记一次 Druid 超时配置的问题 → 引发对 Druid 时间配置项的探究

时间:2022-11-03 12:34:29浏览次数:72  
标签:10 配置 Druid druid connect 超时 连接池 tbl

开心一刻

  一天在路边看到一个街头采访

  记者:请问,假如你儿子娶媳妇,给多少彩礼合适呢

  大爷:一百万吧,再给一套房,一辆车

  大爷沉思一下,继续说到:如果有能力的话再给老丈人配一辆车,毕竟他把女儿养这么大也不容易

  记者:那你儿子多大了?

  大爷:我没有儿子,有两个女儿

记一次 Druid 超时配置的问题 → 引发对 Druid 时间配置项的探究_sql

问题背景

  最近生产环境出现了一个问题,错误日志类似如下

Failed to obtain JDBC Connection; nested exception is com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 1010, active 10, maxActive 10, creating 0, runningSqlCount 10 : select * from tbl_user

JDBC Connection 失败,因为从 druid 连接池获取 connection

  

记一次 Druid 超时配置的问题 → 引发对 Druid 时间配置项的探究_连接池_02

select * from tbl_user 之前,需要从 druid 连接池中获取一个 connect

connect ,连接池最大创建 10 个 connect ,正在执行 sql 的 connect

connect ,那就等呗,一共等了 1010 毫秒,还是拿不到 connect ,就抛出 GetConnectionTimeoutException

connect

  那有人就说了:连接池的最大数量设置大一点,问题不就解决了吗

  最大连接数设置大一点只能说可以降低问题发生的概率,不能完全杜绝,因为网络情况、硬件资源的使用情况等等都是不稳定因素

  今天要讲的不是连接池大小问题,而是超时设置问题,我们慢慢往下看

问题复现

  我们先来模拟下上述问题

MySQL 版本: 5.7.21

Druid 版本: 1.1.12

spring-jdbc 版本: 5.2.3.RELEASE

  DruidDataSource 初始化

  为了方便演示,就手动初始化了

记一次 Druid 超时配置的问题 → 引发对 Druid 时间配置项的探究_sql_03

  多线程查询

connect

记一次 Druid 超时配置的问题 → 引发对 Druid 时间配置项的探究_sql_04

  模拟慢查询

connect

LOCK TABLES tbl_user WRITE

tbl_user 加上写锁,然后跑线程去查询 tbl_user

  异常演示

  先锁表,再启动程序

记一次 Druid 超时配置的问题 → 引发对 Druid 时间配置项的探究_连接池_05

connect

Thread-13 Failed to obtain JDBC Connection; nested exception is com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 10004, active 10, maxActive 10, creating 0, runningSqlCount 10 : select * from tbl_user
Thread-5 Failed to obtain JDBC Connection; nested exception is com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 10004, active 10, maxActive 10, creating 0, runningSqlCount 10 : select * from tbl_user
Thread-10 Failed to obtain JDBC Connection; nested exception is com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 10004, active 10, maxActive 10, creating 0, runningSqlCount 10 : select * from tbl_user
Thread-7 Failed to obtain JDBC Connection; nested exception is com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 10004, active 10, maxActive 10, creating 0, runningSqlCount 10 : select * from tbl_user
Thread-8 Failed to obtain JDBC Connection; nested exception is com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 10004, active 10, maxActive 10, creating 0, runningSqlCount 10 : select * from tbl_user

  示例代码:​​druid-timeout​

时间配置项

Druid

  maxWait

  最大等待时长,单位是毫秒,-1 表示无限制

connect ,如果有空闲的 connect ,则直接获取到,如果没有则最长等待 maxWait 毫秒,如果还获取不到,则抛出 GetConnectionTimeoutException

  removeAbandonedTimeout

  设置 druid 强制回收连接的时限,单位是秒

connect 开始算起,超过此值后, Druid

  官网也有说明:​​连接泄漏监测​

  validationQueryTimeout

  检测连接是否有效的超时时间,单位是秒,-1 表示无限制

Druid 内部的一个检测 connect 是否有效的超时时间,需要结合 validationQuery

  timeBetweenEvictionRunsMillis

  检查空闲连接的频率,单位是毫秒, 非正整数表示不进行检查

Druid 池中的 connect 数量是一个动态从 minIdle 到 maxActive

connect 使用高峰期,数量会从 minIdle 扩张到 maxActive ,使用低峰期, connect 数量会从 maxActive 收缩到 minIdle

connect ,而 timeBetweenEvictionRunsMillis

  queryTimeout

  执行查询的超时时间,单位是秒,-1 表示无限制

Statement 对象上,执行时如果超过此时间,则抛出 SQLException

  transactionQueryTimeout

  执行一个事务的超时时间,单位是秒

  minEvictableIdleTimeMillis

  最小空闲时间,单位是毫秒,默认 30 分钟

minIdle ,并且某些连接的非运行时间大于 minEvictableIdleTimeMillis ,则连接池会将这部分连接设置成 Idle

  maxEvictableIdleTimeMillis

  最大空闲时间,单位是毫秒,默认 7 小时

minIdle 设置的比较大,连接池中的空闲连接数一直没有超过 minIdle

  当然不是,如果连接太久没用,数据库也会把它关闭(MySQL 默认 8 小时),这时如果连接池不把这条连接关闭,程序就会拿到一条已经被数据库关闭的连接

Druid 会判断池中的连接,如果非运行时间大于 maxEvictableIdleTimeMillis ,也会强行把它关闭,而不用判断空闲连接数是否小于 minIdle

再看问题

  其实前面的示例中设置了

记一次 Druid 超时配置的问题 → 引发对 Druid 时间配置项的探究_sql_06

connect 的最大等待时长是 10000 毫秒,也就是 10

removeAbandonedTimeout

connect 如果 7 秒未执行完 SQL 查询,就会被 Druid 强制回收进连接池,那么等待 10 秒应该能够获取到 connect ,为什么会抛出 GetConnectionTimeoutException

  这也就是文章标题中的超时设置问题

源码探究

dataSource.init();

  会看到如下一块代码

记一次 Druid 超时配置的问题 → 引发对 Druid 时间配置项的探究_sql_07

createAndStartDestroyThread();

记一次 Druid 超时配置的问题 → 引发对 Druid 时间配置项的探究_配置项_08

DestroyTask

记一次 Druid 超时配置的问题 → 引发对 Druid 时间配置项的探究_连接池_09

removeAbandoned

记一次 Druid 超时配置的问题 → 引发对 Druid 时间配置项的探究_sql_10

connect

connect 都是在运行中,只是都在进行慢查询,所以是无法被强制回收进连接池的,那么其他线程自然在 maxWait 时间内无法获取到 connect

  至此文章标题中的问题的原因就找到了

removeAbandonedTimeout

  我们再仔细阅读下:​​连接泄漏监测​

Druid 提供了 RemoveAbandanded 相关配置,目的是监测连接泄露,回收那些长时间游离在连接池之外的空闲 connect

connect 在处理完 sql 查询后,不能回到连接池的怀抱,那么这个 connect

removeAbandoned 的设计就是为了帮助这些泄露的 connect

解决问题

removeAbandoned

removeAbandoned

queryTimeout

DataSource 的 queryTimeout ,另一个是设置 JdbcTemplate 的 queryTimeout

  ​​如果两个都设置,最终生效的是哪个,为什么​​?大家自己去分析,权当是给大家留个一个作业

DataSource 的 queryTimeout

记一次 Druid 超时配置的问题 → 引发对 Druid 时间配置项的探究_连接池_11

connect

总结

Druid 的 removeAbandoned

removeAbandoned

Druid

    配置的时候一定要弄清楚各个配置项的具体作业,不要去猜!

queryTimeout 即可在 DataSource 配置,也可在 JdbcTemplate



标签:10,配置,Druid,druid,connect,超时,连接池,tbl
From: https://blog.51cto.com/u_13423706/5819393

相关文章

  • 从源码来理解slf4j的绑定,以及logback对配置文件的加载
    前言项目中的日志系统使用的是slf4j+logback。slf4j作为一个简单日志门面,为各种logingAPIs(像java.util.logging,logback,log4j)提供一个简单统一的接口,有利于维护和......
  • java开发环境搭建及环境变量配置
    一、 JDK的下载与安装jdk下载地址:https://www.oracle.com/java/technologies/downloads/#java8根据电脑系统及位数选择下载对应jdk安装包以下用windows系统为例,jdk安......
  • 配置Squid代理服务器
    添加双网卡vm1是内网同学vm2是外网通信Squid服务器生成外网网卡配置文件外网网卡设置IP地址然后重启服务查看网卡生效了没修改配置文件开启路由功能更新内核参数开启路由转......
  • docker 配置
    docker配置1.镜像加速配置阿里云镜像加速地址:1.1进入管理控制台获取镜像加速器地址:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors 找到私有的加速......
  • 【Eigen】安装与配置
    EigenEigen是C++语言里的一个开源模版库,支持线性代数运算,矩阵和矢量运算,数值分析及其相关的算法。下载和使用EigenEigen下载网站:http://eigen.tuxfamily.org/index......
  • log日志打印配置
    <?xmlversion="1.0"encoding="UTF-8"?><configurationdebug="false"scan="true"scanPeriod="10seconds"><propertyname="APP_NAME"value="clotho-risk-control......
  • 实验环境安装配置
    实验环境安装配置一、实验目的熟悉实验环境熟悉Linux基本操作二、实验要求(一)任务请根据实验环境安装文档,完成特定开源软件的安装(二)实验报告请用Markdown排版,提交在......
  • 华为交换机策略路由配置
    [S5720-core]acl2011rule5permitsource192.168.4.1310[S5720-core]trafficclassifiermail-to-idcif-matchacl2011[S5720-core]trafficbehaviormail-to-idcre......
  • 记linux系统(centos7)的IP地址永久性配置
    记linux系统(centos7)的IP地址永久性配置实验开始:网络配置老几样:IP地址、子网掩码、网关、DNS永久性配置步骤一查看并对照网卡我使用的是NAT模式还要注意去虚拟网络编辑器里......
  • linode ubuntu 的securecrt配置
    ssh连接上去后,发现终端颜色不对对比阿里云上的alias输出vi.bashrc增加aliasegrep='egrep--color=auto'aliasfgrep='fgrep--color=auto'aliasgrep='grep--color=au......