Druid source code reading 8-DruidDataSource's removeAbandoned mechanism

This article has participated in the "Newcomer Creation Ceremony" activity, and started the road of Nuggets creation together

There is a removeAbandoned mechanism for Druid, which was introduced in the getConnection source code. removeAbandoned is actually Druid's leak detection mechanism. The main parameters are:

parameter illustrate
removeAbandoned If the connection leaks, whether to recycle the leaked connection, the default is false;
logAbandoned If the leaked connection is recycled, whether to print a log, the default is false;
removeAbandonedTimeoutMillis The timeout for connection recycling, the default is 5 minutes;

removeAbandoned is used as a switch to enable the connection leak detection mechanism. The default value is false. When it is true, it is regularly detected with the frequency of DestroyTask calls. In the run method of DestroyTask:

@Override
public void run() {
    shrink(true, keepAlive);
    if (isRemoveAbandoned()) {
        removeAbandoned();
    }
}
复制代码

When the connection leak detection mechanism is enabled, it will periodically detect whether the connection triggers the timeout period, and if it triggers, the connection will be closed. All connections used after get are placed in activeConnections. Then traverse activeConnections, judge the connection, and close if the timeout is triggered. The source code of removeAbandoned is as follows:

//定义一个abandonedList来存放符合超时时间的连接。
List<DruidPooledConnection> abandonedList = new ArrayList<DruidPooledConnection>();
//加锁
activeConnectionLock.lock();
try {
     //通过迭代器遍历activeConnections
    Iterator<DruidPooledConnection> iter = activeConnections.keySet().iterator();
	
    for (; iter.hasNext();) {
        //获取到连接
        DruidPooledConnection pooledConnection = iter.next();
		//如果连级为Running状态,说明sql语句正在执行,则跳过当前连接
        if (pooledConnection.isRunning()) {
            continue;
        }
        //计算超时时间 默认值为5分钟
        long timeMillis = (currrentNanos - pooledConnection.getConnectedTimeNano()) / (1000 * 1000);
        //如果触发超时:
        if (timeMillis >= removeAbandonedTimeoutMillis) {
			//从iter删除该连接
            iter.remove();
			//关闭setTraceEnable
            pooledConnection.setTraceEnable(false);
            //添加到abandonedList
            abandonedList.add(pooledConnection);
        }
    }
} finally {
//解锁
    activeConnectionLock.unlock();
}
复制代码

Place connections that meet the timeout condition into the abandonedList. If the abandonedList is not empty, iterate over the abandonedList and close the connections:

//定义锁
final ReentrantLock lock = pooledConnection.lock;
lock.lock();
try {
    //如果连接为disiable状态 说明已经不可用 直接跳过
    if (pooledConnection.isDisable()) {
        continue;
    }
} finally {
    //解锁
    lock.unlock();
}
//关闭连接
JdbcUtils.close(pooledConnection);
//设置abandond状态
pooledConnection.abandond();
//增加计数器
removeAbandonedCount++;
removeCount++;
复制代码

Log processing is then performed. After printing the warn log, the method is executed.

Guess you like

Origin juejin.im/post/7078497281242038302