使用Durid连接池出现wait_timeout错误分析

使用Durid连接池出现wait_timeout错误分析

前言

最近其他团队使用hive的jdbcTemplate操作的时候出现了wait_timeout错误,经过定位是因为mysql数据库的wait_timeout设置的时间为1800秒(默认为28800秒即8个小时)。hive的元数据是存在mysql当中的,hiveserver默认的连接池是bonecp(新版本改成了HikariCP),当前使用的hive版本只对连接池的几个配置项作为参数值进行设置(连接超时时间、最大连接数、分区数、用户、密码),其他均使用的连接池默认配置。而连接池的探活时间配置目前还未作为配置项(因此当前机制使用的是连接池默认的 4 小时)。
由此也研究下项目中用到的Durid连接池。
在这里插入图片描述

Durid连接池核心的配置

Durid连接池一般有几个核心的配置:

<!-- 配置初始化大小、最小、最大 -->
        <property name="initialSize" value="5" />
        <property name="minIdle" value="5" />
        <property name="maxActive" value="10" />
        <!-- 配置从连接池获取连接等待超时的时间 -->
        <property name="maxWait" value="10000" />
 
        <!-- 配置间隔多久启动一次DestroyThread,对连接池内的连接才进行一次检测,单位是毫秒。
            检测时:1.如果连接空闲并且超过minIdle以外的连接,如果空闲时间超过minEvictableIdleTimeMillis设置的值则直接物理关闭。2.在minIdle以内的不处理。
        -->
        <property name="timeBetweenEvictionRunsMillis" value="60000" />
 
        <!-- 配置一个连接在池中最大空闲时间,单位是毫秒 -->
        <property name="minEvictableIdleTimeMillis" value="300000" />
 
        <!-- 设置从连接池获取连接时是否检查连接有效性,true时,每次都检查;false时,不检查 -->
        <property name="testOnBorrow" value="false" />
 
        <!-- 设置往连接池归还连接时是否检查连接有效性,true时,每次都检查;false时,不检查 -->
        <property name="testOnReturn" value="false" />
 
        <!-- 设置从连接池获取连接时是否检查连接有效性,true时,如果连接空闲时间超过minEvictableIdleTimeMillis进行检查,否则不检查;false时,不检查 -->
        <property name="testWhileIdle" value="true" />
 
        <!-- 检验连接是否有效的查询语句。如果数据库Driver支持ping()方法,则优先使用ping()方法进行检查,否则使用validationQuery查询进行检查。(Oracle jdbc Driver目前不支持ping方法) -->
        <property name="validationQuery" value="select 1 from dual" />
 
        <!-- 打开后,增强timeBetweenEvictionRunsMillis的周期性连接检查,minIdle内的空闲连接,每次检查强制验证连接有效性. 参考:https://github.com/alibaba/druid/wiki/KeepAlive_cn -->
        <property name="keepAlive" value="true" />  

其中几个关键的逻辑:

  1. timeBetweenEvictionRunsMillis是调度间隔的时间,会检查非核心连接,如果空闲时间超过minEvictableIdleTimeMillis设置的值则直接物理关闭。
  2. testWhileIdle建议开启,每次从连接池中获取连接的时候,如果连接空闲时间超过minEvicatbleIdleTimeMilies都会检查是否有效,如果失效的话,销毁当前的连接,继续在池中获取可用连接,如果整个池中的连接都是无效的,会创建新的连接。
    minEvicatbleIdleTimeMilies配置的时间一般都会小于数据库的wait_timeout (mysql默认是8小时)时间,不会出现连接到数据库的连接是关闭的情况。
  3. keepAlive开启后,是增强timeBetweenEvictionRunsMillis的周期性连接检查,minIdle内的空闲连接,每次若空闲时间超过keepAliveBetweenTimeMillis检查强制验证连接有效性,若有效会更新空闲时间。如果失效的话,销毁当前的连接。
    主要作用是保持了druid连接池的连接的的活性,同时也保活了数据库的连接池,如果minIdle连接数据较多,会使数据库的可用连接变少。
    keepAlive开启后,会减少每次从连接池中获取连接时的检查。
    需要注意的是,keepAliveBetweenTimeMillis保活的时间间隔,默认为1分钟,一般不需要更改其配置,如果minEvicatbleIdleTimeMilies小于keepAliveBetweenTimeMillis,会使连接池中的所有连接都在保活,会给数据库造成较大的压力。

简单的流程如下:
在这里插入图片描述

总结

综上:
如果设置了testWhileIdle为true,minEvictableIdleTimeMillis不要过大,基本不会出现连接数据库连接是关闭的问题;
如果设置了keepAlive为true,minIdle不宜设置的过大,同时timeBetweenEvictionRunsMillis不宜设置的过于频繁。

参考资料

  1. https://github.com/alibaba/druid/wiki/DruidDataSource%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E5%88%97%E8%A1%A8
  2. https://github.com/alibaba/druid/wiki/DruidDataSource%E9%85%8D%E7%BD%AE
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值