聊聊druid的源码的几个疑问

2023-10-06 14:25:24 浏览数 (2)

本文主要聊一聊druid源码的几个疑问

asyncCloseConnectionEnable

druid-1.2.11-sources.jar!/com/alibaba/druid/pool/DruidPooledConnection.java

代码语言:javascript复制
    public void close() throws SQLException {
        if (this.disable) {
            return;
        }

        DruidConnectionHolder holder = this.holder;
        if (holder == null) {
            if (dupCloseLogEnable) {
                LOG.error("dup close");
            }
            return;
        }

        DruidAbstractDataSource dataSource = holder.getDataSource();
        boolean isSameThread = this.getOwnerThread() == Thread.currentThread();

        if (!isSameThread) {
            dataSource.setAsyncCloseConnectionEnable(true);
        }

        if (dataSource.isAsyncCloseConnectionEnable()) {
            syncClose();
            return;
        }

        //......
    }    

DruidPooledConnection的close方法会判断dataSource.isAsyncCloseConnectionEnable(),但是奇怪的是为true的话,执行的却是syncClose方法

numTestsPerEvictionRun

druid-1.2.11-sources.jar!/com/alibaba/druid/pool/DruidAbstractDataSource.java

代码语言:javascript复制
	protected volatile int numTestsPerEvictionRun = DEFAULT_NUM_TESTS_PER_EVICTION_RUN;

	public static final int DEFAULT_NUM_TESTS_PER_EVICTION_RUN = 3;

    public int getNumTestsPerEvictionRun() {
        return numTestsPerEvictionRun;
    }

    /**
     * @param numTestsPerEvictionRun
     */
    @Deprecated
    public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
        this.numTestsPerEvictionRun = numTestsPerEvictionRun;
    }

DruidAbstractDataSource定义了numTestsPerEvictionRun属性,不过看set方法标记为废弃了,搜了一下代码,实际没有使用到

timeBetweenEvictionRunsMillis

druid-1.2.11-sources.jar!/com/alibaba/druid/pool/DruidAbstractDataSource.java

代码语言:javascript复制
protected volatile long timeBetweenEvictionRunsMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;

public static final long DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS = 60 * 1000L;

DruidAbstractDataSource定义了timeBetweenEvictionRunsMillis,但是这个却是在getConnectionDirect的时候使用

druid-1.2.11-sources.jar!/com/alibaba/druid/pool/DruidDataSource.java

代码语言:javascript复制
    public DruidPooledConnection getConnectionDirect(long maxWaitMillis) throws SQLException {
    	for (; ; ) {
    		// get connection
    		if (testOnBorrow) {
    			// testConnectionInternal
    		} else {
    			if (testWhileIdle) {
                    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;
                        }
                    }
    			}
    		}

    		//......
    	}

    }

这里用idleMillis去跟timeBetweenEvictionRunsMillis比较,似乎timeBetweenEvictionRunsMillis变量的命名不符合语义,不过它真正的用途是在DestroyConnectionThread里头,在那里才符合它命名的语义

小结

整体代码看下来感觉跟commons-pool相比,druid代码的实现感觉有点粗糙,抽象层级不够高,代码充斥大量统计标记、状态位的处理,维护起来得很小心。另外还有如下几个:

  • DruidPooledConnection的close方法会判断dataSource.isAsyncCloseConnectionEnable(),但是奇怪的是为true的话,执行的却是syncClose方法
  • DruidAbstractDataSource定义了numTestsPerEvictionRun属性,不过看set方法标记为废弃了,搜了一下代码,实际没有使用到
  • DruidAbstractDataSource定义了timeBetweenEvictionRunsMillis,但是这个却是在getConnectionDirect的时候使用,用idleMillis去跟timeBetweenEvictionRunsMillis比较,似乎timeBetweenEvictionRunsMillis变量的命名不符合语义,不过它真正的用途是在DestroyConnectionThread里头,在那里才符合它命名的语义
  • DruidDataSource配置属性列表这里的信息已经过时了也没有纠正过来,比如testOnBorrow现在默认是false
  • 虽然提供了stat页面,但是微服务之后,这项功能基本也没啥用了,一般需要通过metrics集成起来

doc

  • 定时连接有效性检查的支持 #1281

0 人点赞