Druid源码阅读10-哪些情况下会丢弃连接?

1.DruidDataSource.shrink(boolean checkTime)方法中异步线程 DestroyTask 对无效的Collection做清除

public void shrink(boolean checkTime) {
    final List<DruidConnectionHolder> evictList = new ArrayList<DruidConnectionHolder>();
    try {
        lock.lockInterruptibly();
    } catch (InterruptedException e) {
        return;
    }
 
    try {
        final int checkCount = poolingCount - minIdle;
        final long currentTimeMillis = System.currentTimeMillis();
        for (int i = 0; i < poolingCount; ++i) {
            DruidConnectionHolder connection = connections[i];
 
            if (checkTime) {
 
                ## 连接不管是否空闲,存活phyTimeoutMillis后强制回收,用于Destroy线程清理连接的时候的检测时间,如果不配置默认等于-1,也就是此处不检查
                if (phyTimeoutMillis > 0) {
                    long phyConnectTimeMillis = currentTimeMillis - connection.getTimeMillis();
                    if (phyConnectTimeMillis > phyTimeoutMillis) {
                        evictList.add(connection);
                        continue;
                    }
                }
 
                long idleMillis = currentTimeMillis - connection.getLastActiveTimeMillis();
 
                if (idleMillis < minEvictableIdleTimeMillis) {
                    break;
                }
 
                if (checkTime && i < checkCount) {
                    evictList.add(connection);
                } else if (idleMillis > maxEvictableIdleTimeMillis) {
                    ## 连接的最大存活时间,如果连接的最大时间大于 maxEvictableIdleTimeMillis ,则无视最小连接数强制回收
                    evictList.add(connection);
                }
            } else {
                if (i < checkCount) {
                    evictList.add(connection);
                } else {
                    break;
                }
            }
        }
 
        int removeCount = evictList.size();
        if (removeCount > 0) {
            System.arraycopy(connections, removeCount, connections, 0, poolingCount - removeCount);
            Arrays.fill(connections, poolingCount - removeCount, poolingCount, null);
            poolingCount -= removeCount;
        }
    } finally {
        lock.unlock();
    }
 
    for (DruidConnectionHolder item : evictList) {
        Connection connection = item.getConnection();
        JdbcUtils.close(connection);
        destroyCount.incrementAndGet();
    }
}

2.DruidDataSource.removeAbandoned() 方法中异步线程 DestroyTask 对无效的Collection做清除

public int removeAbandoned() {
        int removeCount = 0;
 
        long currrentNanos = System.nanoTime();
 
        List<DruidPooledConnection> abandonedList = new ArrayList<DruidPooledConnection>();
 
        synchronized (activeConnections) {
            Iterator<DruidPooledConnection> iter = activeConnections.keySet().iterator();
 
            for (; iter.hasNext();) {
                DruidPooledConnection pooledConnection = iter.next();
 
                if (pooledConnection.isRunning()) {
                    continue;
                }
 
                long timeMillis = (currrentNanos - pooledConnection.getConnectedTimeNano()) / (1000 * 1000);
 
               ## 通过datasource.getConnontion() 取得的连接必须在removeAbandonedTimeout这么多秒内调用close()要不我就弄死你.(就是conn不能超过指定的租期);removeAbandonedTimeoutMillis=默认300 * 1000 5分钟
                if (timeMillis >= removeAbandonedTimeoutMillis) {
                    iter.remove();
                    pooledConnection.setTraceEnable(false);
                    abandonedList.add(pooledConnection);
                }
            }
        }
 
        if (abandonedList.size() > 0) {
            for (DruidPooledConnection pooledConnection : abandonedList) {
                synchronized (pooledConnection) {
                    if (pooledConnection.isDisable()) {
                        continue;
                    }
                }
 
                JdbcUtils.close(pooledConnection);
                pooledConnection.abandond();
                removeAbandonedCount++;
                removeCount++;
                省略...
            }
        }
 
        return removeCount;
    }

3.DruidDataSource. getConnecltionDirect(long maxWaitMillis) :检查空闲连接是否有效,如果连接无效关闭连接,再新建一个可用连接

 if (isTestWhileIdle()) {
	final long currentTimeMillis = System.currentTimeMillis();
	final long lastActiveTimeMillis = poolableConnection.getConnectionHolder().getLastActiveTimeMillis();
	final long idleMillis = currentTimeMillis - lastActiveTimeMillis;
	long timeBetweenEvictionRunsMillis = this.getTimeBetweenEvictionRunsMillis();
	if (timeBetweenEvictionRunsMillis <= 0) {
		timeBetweenEvictionRunsMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
	}
	## 获取连接的时候,检查连接的空闲时间,如果空间时间大于配置的时间,检测连接是否还有效,如果连接无效关闭连接,无效连接关闭了后再新建一个可用连接
	if (idleMillis >= timeBetweenEvictionRunsMillis) {
		boolean validate = testConnectionInternal(poolableConnection.getConnection());
		if (!validate) {
			if (LOG.isDebugEnabled()) {
				LOG.debug("skip not validate connection.");
			}

			discardConnection(realConnection);
			continue;
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值