美文网首页MySQLDruidDruid
Druid配置参数详解-testWhileIdle

Druid配置参数详解-testWhileIdle

作者: codeimport | 来源:发表于2020-01-03 12:02 被阅读0次

    Druid配置参数详解-testWhileIdle

    Druid是一个由阿里开源的数据库连接池,Druid的配置非常丰富,但是设置不当会对生产环境造成严重影响,网上Druid的资料虽多,但大部分都是互相复制粘贴,有很多不准确甚至完全错误的描述,Druid已经开源很久,而且作者WenShao的工作重心也已经不在Druid上,有些功能估计他自己都不太了解了。本系列将从源代码的角度分析Druid目前的最新版本(1.1.21)各个常用的配置项的具体含义以及是怎么起作用的。

    画外音:目前Druid在开源中国举办的2019年度最受欢迎中国开源软件中排名第7名,支持Druid的朋友可以去投票哇。2019年度最受欢迎中国开源软件

    testWhileIdle是什么意思?

    testWhileIdle:如果为true(默认true),当应用向连接池申请连接,并且testOnBorrow为false时,连接池将会判断连接是否处于空闲状态,如果是,则验证这条连接是否可用。

    testWhileIdle什么时候会起作用?

    1. 获取连接时;
    2. testOnBorrow==false;
    3. testWhileIdle==true;

    使用代码在DruidDataSource的getConnectionDirect方法
    注意:此时判断连接空闲的依据是空闲时间大于timeBetweenEvictionRunsMillis(默认1分钟),并不是使用minEvictableIdleTimeMillis跟maxEvictableIdleTimeMillis也就是说如果连接空闲时间超过一分钟就测试一下连接的有效性,但并不是直接剔除;而如果空闲时间超过了minEvictableIdleTimeMillis则会直接剔除。

    if (testOnBorrow) {
                    boolean validate = testConnectionInternal(poolableConnection.holder, poolableConnection.conn);
                    if (!validate) {
                        if (LOG.isDebugEnabled()) {
                            LOG.debug("skip not validate connection.");
                        }
    
                        discardConnection(poolableConnection.holder);
                        continue;
                    }
                } else {
                    if (poolableConnection.conn.isClosed()) {
                        discardConnection(poolableConnection.holder); // 传入null,避免重复关闭
                        continue;
                    }
    
                    if (testWhileIdle) {
                        final DruidConnectionHolder holder = poolableConnection.holder;
                        long currentTimeMillis             = System.currentTimeMillis();
                        long lastActiveTimeMillis          = holder.lastActiveTimeMillis;
                        long lastExecTimeMillis            = holder.lastExecTimeMillis;
                        long lastKeepTimeMillis            = holder.lastKeepTimeMillis;
    
                        if (checkExecuteTime
                                && lastExecTimeMillis != lastActiveTimeMillis) {
                            lastActiveTimeMillis = lastExecTimeMillis;
                        }
    
                        if (lastKeepTimeMillis > lastActiveTimeMillis) {
                            lastActiveTimeMillis = lastKeepTimeMillis;
                        }
    
                        long idleMillis                    = currentTimeMillis - lastActiveTimeMillis;
    
                        long timeBetweenEvictionRunsMillis = this.timeBetweenEvictionRunsMillis;
    
                        if (timeBetweenEvictionRunsMillis <= 0) {
                            timeBetweenEvictionRunsMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
                        }
    
                        if (idleMillis >= timeBetweenEvictionRunsMillis
                                || idleMillis < 0 // unexcepted branch
                                ) {
                            boolean validate = testConnectionInternal(poolableConnection.holder, poolableConnection.conn);
                            if (!validate) {
                                if (LOG.isDebugEnabled()) {
                                    LOG.debug("skip not validate connection.");
                                }
    
                                discardConnection(poolableConnection.holder);
                                 continue;
                            }
                        }
                    }
                }
    

    连接池是如何判断连接是否有效的?

    判断连接是否可用同testOnBorrow
    Druid配置参数详解-testOnBorrow

    总结

    testWhileIdle的作用跟testOnBorrow是差不多的,都是在获取连接的时候测试连接的有效性,如果两者都为true,则testOnBorrow优先级高,则不会使用到testWhileIdle。

    相关文章

      网友评论

        本文标题:Druid配置参数详解-testWhileIdle

        本文链接:https://www.haomeiwen.com/subject/kcjzoctx.html