1、获取连接和初始化
连接池内的连接数等于0,则唤醒创建物理连接的线程或任务,并将当前线程阻塞,当连接被创建或回收后唤醒被阻塞的线程,其次被阻塞的线程支持中断。
2、获取连接
获取连接的时候也会先去检查一下连接池是否已经初始化,如果没有初始化则先进行初始化。
public DruidPooledConnection getConnection(long maxWaitMillis) throws SQLException {
//maxWaitMillis 从连接池获取连接最大等待时间(默认-1 一直等待)
init();
if (filters.size() > 0) {
//Filter被加载则通过责任链的方式调用
FilterChainImpl filterChain = new FilterChainImpl(this);
return filterChain.dataSource_connect(this, maxWaitMillis);
} else {
//使用直接获取连接的方式
return getConnectionDirect(maxWaitMillis);
}
}
3、责任链执行
//Filter开始下标
protected int pos = 0;
//连接池对象
private final DataSourceProxy dataSource;
//Filter的Size
private final int filterSize;
//获取连接会创建新的对象执行责任链
public FilterChainImpl(DataSourceProxy dataSource){
this.dataSource = dataSource;
this.filterSize = getFilters().size();
}
//获取Filter之后pos+1
private Filter nextFilter() {
return getFilters().get(pos++);
}
//责任链执行
public DruidPooledConnection dataSource_connect(DruidDataSource dataSource, long maxWaitMillis)
throws SQLException {
//每次从0开始执行执行后pos+1
if (this.pos < filterSize) {
//通过递归方式调用
DruidPooledConnection conn = nextFilter().dataSource_getConnection(this, dataSource,
maxWaitMillis);
return conn;
}
//责任链执行完后直接获取连接
return dataSource.getConnectionDirect(maxWaitMillis);
}
//StatFilter执行回调到chain获取到连接后在执行
public DruidPooledConnection dataSource_getConnection(FilterChain chain, DruidDataSource dataSource,
long maxWaitMillis) throws SQLException {
//回调到chain来执行
DruidPooledConnection conn = chain.dataSource_connect(dataSource, maxWaitMillis);
if (conn != null) {
conn.setConnectedTimeNano();
StatFilterContext.getInstance().pool_connection_open();
}
return conn;
}
4、getConnectionDirect
public DruidPooledConnection getConnectionDirect(long maxWaitMillis) throws SQLException {
int notFullTimeoutRetryCnt = 0;
//获取连接异常或判断不可用则会重新获取连接
for (;;) {
DruidPooledConnection poolableConnection;
try {
//获取连接
poolableConnection = getConnectionInternal(maxWaitMillis);
} catch (GetConnectionTimeoutException ex) {
//判断是否重试
if (notFullTimeoutRetryCnt <= this.notFullTimeoutRetryCount && !isFull()) {
continue;
}
throw ex;
}
//测试连接的可用性
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()) {
//将连接close
discardConnection(poolableConnection.holder);
continue;
}
//测试连接的空闲时间
if (testWhileIdle) {
...
//空闲时间>=timeBetweenEvictionRunsMillis (默认1分钟)
if (idleMillis >= timeBetweenEvictionRunsMillis || idleMillis < 0 ) {
//执行检测连接是否有效
boolean validate = testConnectionInternal(poolableConnection.holder, poolableConnection.conn);
if (!validate) {
if (LOG.isDebugEnabled()) {
LOG.debug("skip not validate connection.");
}
//连接不可以则将连接丢弃
discardConnection(poolableConnection.holder);
continue;
}
}
}
}
//配置连接回收
if (removeAbandoned) {
...
try {
//将连接put到activeConnections Map中
activeConnections.put(poolableConnection, PRESENT);
} finally {
activeConnectionLock.unlock();
}
}
if (!this.defaultAutoCommit) {
poolableConnection.setAutoCommit(false);
}
//返回最终的连接对象
return poolableConnection;
}
}
testWhileIdle 申请连接的时候检测是否有效。
timeBetweenEvictionRunsMillis 连接空闲时间超过则测试连接的有效性,默认1分钟。
5、getConnectionInternal
private DruidPooledConnection getConnectionInternal(long maxWait) throws SQLException {
//判断连接池是否关闭
if (closed) {
...
throw new DataSourceClosedException();
}
//判断连接池是否禁用
if (!enable) {
...
throw new DataSourceDisableException();
}
final long nanos = TimeUnit.MILLISECONDS.toNanos(maxWait);
final int maxWaitThreadCount = this.maxWaitThreadCount;
DruidConnectionHolder holder;
for (boolean createDirect = false;;) {
//创建连接的标志
if (createDirect) {
createStartNanosUpdater.set(this, System.nanoTime());
if (creatingCountUpdater.compareAndSet(this, 0, 1)) {
//使用创建线程池的定时任务创建连接
PhysicalConnectionInfo pyConnInfo = DruidDataSource.this.createPhysicalConnection();
...
}
}
...
try {
//获取连接池时先获取锁
lock.lockInterruptibly();
} catch (InterruptedException e) {
connectErrorCountUpdater.incrementAndGet(this);
throw new SQLException("interrupt", e);
}
try {
//连接不够用时最多让多少线程发生阻塞(默认-1)
if (maxWaitThreadCount > 0
&& notEmptyWaitThreadCount >= maxWaitThreadCount) {
connectErrorCountUpdater.incrementAndGet(this);
throw new SQLException("maxWaitThreadCount " + maxWaitThreadCount + ", current wait Thread count " + lock.getQueueLength());
}
//发生致命错误
if (onFatalError
&& onFatalErrorMaxActive > 0
&& activeCount >= onFatalErrorMaxActive) {
connectErrorCountUpdater.incrementAndGet(this);
StringBuilder errorMsg = new StringBuilder();
errorMsg.append("onFatalError, activeCount ")
.append(activeCount)
.append(", onFatalErrorMaxActive ")
.append(onFatalErrorMaxActive);
...
throw new SQLException(errorMsg.toString(), lastFatalError);
}
connectCount++;
//创建线程的线程不为空,并且线程池连接数等于0,并且活动线程小于最大线程
if (createScheduler != null
&& poolingCount == 0
&& activeCount < maxActive
&& creatingCountUpdater.get(this) == 0
&& createScheduler instanceof ScheduledThreadPoolExecutor) {
ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor) createScheduler;
if (executor.getQueue().size() > 0) {
//将创建连接的状态设为true,结束本次循环
createDirect = true;
continue;
}
}
//从连接池获取连接
if (maxWait > 0) {
holder = pollLast(nanos);
} else {
holder = takeLast();
}
if (holder != null) {
if (holder.discard) {
continue;
}
//活动线程+1
activeCount++;
holder.active = true;
if (activeCount > activePeak) {
activePeak = activeCount;
activePeakTime = System.currentTimeMillis();
}
}
} catch (InterruptedException e) {
connectErrorCountUpdater.incrementAndGet(this);
throw new SQLException(e.getMessage(), e);
} catch (SQLException e) {
connectErrorCountUpdater.incrementAndGet(this);
throw e;
} finally {
lock.unlock();
}
break;
}
//未获得连接对象,抛出异常
if (holder == null) {
long waitNanos = waitNanosLocal.get();
final long activeCount;
final long maxActive;
final long creatingCount;
final long createStartNanos;
final long createErrorCount;
final Throwable createError;
try {
lock.lock();
activeCount = this.activeCount;
maxActive = this.maxActive;
creatingCount = this.creatingCount;
createStartNanos = this.createStartNanos;
createErrorCount = this.createErrorCount;
createError = this.createError;
} finally {
lock.unlock();
}
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);
}
}
if (createErrorCount > 0) {
buf.append(", createErrorCount ").append(createErrorCount);
}
List<JdbcSqlStatValue> sqlList = this.getDataSourceStat().getRuningSqlList();
for (int i = 0; i < sqlList.size(); ++i) {
if (i != 0) {
buf.append('\n');
} else {
buf.append(", ");
}
JdbcSqlStatValue sql = sqlList.get(i);
buf.append("runningSqlCount ").append(sql.getRunningCount());
buf.append(" : ");
buf.append(sql.getSql());
}
String errorMessage = buf.toString();
//获取连接超时异常
if (createError != null) {
throw new GetConnectionTimeoutException(errorMessage, createError);
} else {
throw new GetConnectionTimeoutException(errorMessage);
}
}
//连接次数+1
holder.incrementUseCount();
DruidPooledConnection poolalbeConnection = new DruidPooledConnection(holder);
return poolalbeConnection;
}
6、从连接池获取连接
DruidConnectionHolder takeLast() throws InterruptedException, SQLException {
try {
//可用的连接 == 0
while (poolingCount == 0) {
//唤醒创建线程池的线程
emptySignal();
if (failFast && isFailContinuous()) {
throw new DataSourceNotAvailableException(createError);
}
notEmptyWaitThreadCount++;
if (notEmptyWaitThreadCount > notEmptyWaitThreadPeak) {
notEmptyWaitThreadPeak = notEmptyWaitThreadCount;
}
try {
//将当前线程阻塞,通过回收或创建者唤醒
notEmpty.await();
} finally {
notEmptyWaitThreadCount--;
}
notEmptyWaitCount++;
if (!enable) {
connectErrorCountUpdater.incrementAndGet(this);
if (disableException != null) {
throw disableException;
}
throw new DataSourceDisableException();
}
}
} catch (InterruptedException ie) {
notEmpty.signal(); // propagate to non-interrupted thread
notEmptySignalCount++;
throw ie;
}
//连接对象返回,将可用连接数减一,并且将连接池对应的位置设为空
decrementPoolingCount();
DruidConnectionHolder last = connections[poolingCount];
connections[poolingCount] = null;
return last;
}