1、连接如何创建的?
创建连接的方法
com.alibaba.druid.pool.DruidAbstractDataSource#createPhysicalConnection()
2、连接如何回收的?
持续更新。。。
3、哪些情况下会丢弃连接?
持续更新。。。
4、哪些情况下会创建新连接?
创建新连接的几个时机
4-1、第一次getConnection时创建连接,init()
异步创建:配置了ScheduledExecutorService并且配置了异步创建,将任务提交给createConnectionTask线程去创建,创建8个连接,超过后1.5倍扩容createTasks,该数组用于记录DruidDataSource的createTaskIdSeed变量也就是taskId(通过AtomicLongFieldUpdater方式原子性更新DruidDataSource中非原子的"createTaskIdSeed"成员变量)。
if (createScheduler != null && asyncInit) {
for (int i = 0; i < initialSize; ++i) {
submitCreateTask(true);
}
}
创建连接方法:com.alibaba.druid.pool.DruidAbstractDataSource#createPhysicalConnection()
4-2、getConnectionDirect(long maxWaitMillis)
init只会初始化1次,之后再拿连接直接通过getConnectionDirect()方法获取连接;
testOnBorrow:每次从池中借连接时都要检测连接的有效性,若连接无效时会close掉这个连接,并且池中连接数小于minIdle时会发送empty信号去尝试创建新连接;
testWhileIdle:并不会每次拿连接都要去检测,当空闲时间超过指定检测周期(默认1分钟)时会校验连接活性,失效可能发送empty信号尝试创建新连接;
4-3、removeAbandoned机制
销毁线程destroyTask触发removeAbandoned,会检测连接活性,长时间未关闭的连接会放入驱逐容器abandonedList中执行丢弃操作,也会触发close操作,并有可能触发emptySignal();
4-4、emptySignal(),唤醒生产者去创建连接
init():开启keepAlive保活机制时
discardConnection(DruidConnectionHolder holder):丢弃连接时
handleFatalError(DruidPooledConnection conn, SQLExeption error,String sql):发生SQLExeption时
takeLast()/pollLast():获取connections数组尾部连接时,会判段是否有可用连接,如果没有则发送empty信号给生产者
shrink():销毁连接的守护线程会定时循环destroyTask线程,destroyTask线程执行shrink方法,在保活校验时,如果发现这个连接已经无效了,那么判断如果connections池内可用连接+active的连接 < minIdle,那么会发送empty信号给生产者