程序员

Druid配置参数详解-maxWait

2019-12-31  本文已影响0人  codeimport

Druid配置参数详解-maxWait

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

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

maxWait是什么意思?

maxWait:从连接池中获取连接的最大等待时间,单位ms,默认-1,即会一直等待下去

为什么要设置这个参数?

笔者在使用Druid时都会设置这个参数,这样如果是获取连接超时,更容易从日志中获取调用失败的原因。

如果超时,Druid会抛出以下异常

Caused by: com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 3000, active 4, maxActive 4, creating 0
    at com.alibaba.druid.pool.DruidDataSource.getConnectionInternal(DruidDataSource.java:1722)
    at com.alibaba.druid.pool.DruidDataSource.getConnectionDirect(DruidDataSource.java:1402)
    at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:5059)
    at com.alibaba.druid.filter.logging.LogFilter.dataSource_getConnection(LogFilter.java:886)
    at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:5055)
    at com.alibaba.druid.filter.FilterAdapter.dataSource_getConnection(FilterAdapter.java:2756)
    at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:5055)
    at com.alibaba.druid.filter.stat.StatFilter.dataSource_getConnection(StatFilter.java:680)
    at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:5055)
    at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:1380)
    at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:1372)
    at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:109)
    at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:262)
    ... 11 more

maxWait是怎么起作用的?

在DruidDataSource中的getConnectionInternal方法使用到了maxWait

    private DruidPooledConnection getConnectionInternal(long maxWait) throws SQLException {
        if (closed) {
            connectErrorCountUpdater.incrementAndGet(this);
            throw new DataSourceClosedException("dataSource already closed at " + new Date(closeTimeMillis));
        }
    }

        //此处省略部分代码
        if (maxWait > 0) {
             //获取连接,如果超时将返回null
              holder = pollLast(nanos);
        } else {
              holder = takeLast();
        }
                
        //此处省略部分代码
        //如果超时,则holder返回null,然后抛出异常
        if (holder == null) {
            long waitNanos = waitNanosLocal.get();

            StringBuilder buf = new StringBuilder(128);
            buf.append("wait millis ")//
               .append(waitNanos / (1000 * 1000))//
               .append(", active ").append(activeCount)//
               .append(", maxActive ").append(maxActive)//
               .append(", creating ").append(creatingCount)//
            ;
            if (creatingCount > 0 && createStartNanos > 0) {
                long createElapseMillis = (System.nanoTime() - createStartNanos) / (1000 * 1000);
                if (createElapseMillis > 0) {
                    buf.append(", createElapseMillis ").append(createElapseMillis);
                }
            }
        }

总结

maxWait默认是不超时,即如果连接池没有空闲连接,则会一直等待下去,但是一般的接口都是有超时时间的,如果接口超时,不方便定位出来是获取不到连接导致的,最好设置maxWait,并且小于接口的超时时间。

上一篇下一篇

猜你喜欢

热点阅读