druid 原理流程图
2022-07-22 09:54:19 16 举报
druid 原理流程图
作者其他创作
大纲/内容
获取链接 - 4 - 关闭连接
从数组 connections 中获取,并返回
已经被 close,就丢弃
还是 0 个连接
pollLast
testWhileIdle
notEmpty.signal(),唤醒获取连接的线程
2.1.1.5: 根据 initialSize 进行初始化连接()
报错退出
获取用户名、密码、连接配置,根据不同的驱动,利用 JDBC 创建连接
DruidDataSource
getConnection
连接池初始化
清理连接的线程
获取的连接对象是否已经被 close
会将连接对象放到 activeConntions 的 Map 里面key = 连接对象,value = new Object()【防止连接泄漏】【会通过一个守护线程去抛弃占用超时的连接】【默认超时时间是 5 分钟】
否
2.1: getConnection(maxWait默认-1)
validationQueryTimeout
testOnBorrow获取连接是否测试连接有用
poolingCount == 0 连接池可用是否为 0 【循环】
activeCount + poolingCount >= maxActive
开启了回收时检测
执行 close 的线程是否跟使用该连接对象的线程是同一个
removeAbandoned 开启了 && pooledConnection.traceEnable
获取链接 - 3 - 测试连接的可用性
keepAlive
获取连接超时 || maxActive
总体的连接数 = 最大连接数
defaultAutoCommit是否自动提交事务
recycle
timeBetweenEvictionRunsMillis
责任链
是
validationQuery
1、evictConnections 数组:超过 minIdle 的连接如果空闲时间 > minEvictableIdleTimeMillis,则进行回收;回收方式:对 evictConnections 数组进行逐一 close2、keepAliveConnections 数组:minIdle 内的连接在 keepAlive 设置为 true 时,如果空闲时间 > keepAliveBetweenTimeMills,进行保活保活方式:对 keepAliveConnections 数组内的连接进行逐一可用性检测,如果不可用直接丢弃,若可用则重写放回连接池
主动回收长期未归还的连接一个连接被从连接池拿出来后处于使用中的状态,如果 removeAbandoned 设置为 true,则这些连接将会保存到 activeConnections 中,如果一个连接取出来的时间超过 removeAbandonedTimeoutMillis 则直接对该连接进行强制回收这样做是为了防止连接未 close 而导致连接泄漏,当然目前的 orm 框架在使用完连接后会主动 close,所以在生成环境中 removeAbandoned 不建议开启
poolingCount == 0 连接池可用是否为 0 如果还是 0 则再 continue
removeAbandoned
new DruidDataSource
创建连接的线程被唤醒
getConnectionInternal
池子的连接数 最大连接数,才往池子里面放
已经有了连接,就去获取返回
discardConnection
获取链接 - 1
手动清理连接
run 方法
shrink
removeAbandonedTimeoutMillis
2.1.1.1: 过滤器()
死循环
2.1.1.2: JDBC参数()
继续下一次循环
【初始化三大线程】1、异步线程:createAndLogThread,如果设置了 timeBetweenLogStatsMills 则开启守护线程,收集监控指标打印 Log 日志2、异步线程:createAndStartCreatorThread,负责添加连接的守护线程,【通过 countDown 来保证这两个线程启动完成】3、异步线程:createAndStartDestroyThread,负责销毁连接的守护线程,【通过 countDown 来保证这两个线程启动完成】
包装 new DruidConnectionHolder 并 put 到池子里
自动提交 || 只读
当前获取连接的线程进行阻塞等待被唤醒,再走下面
poolingCOunt == 0 连接池可用是否为 0 【循环】
removeAbandoned连接占用超时是否强制回收
2: getConnection()
maxWait
createPhysicalConnection,创建物理连接对象
empty.await
poolingCount >= maxActive
2.1.1.6: 三大线程()
检测如果不可用直接丢弃连接
开启了强制回收
是否有等待获取连接的线程
holder.reset()
minEvictableIdleTimeMillis
创建连接的线程
1.1: super()
【初始化过滤器(监控就是用过滤器实现的)】1、加载自定义设置的 Filter(如:stat) 并 init2、后面方法通过 SPI 加载第三方 Filter 并 init,不过第三方实现要加上 AutoLoad.class 注解
【初始化 ValidConnectionChecker】1、initValidConnectionChecker();连接的可用性检测
如果放失败了,则直接关闭连接
return null
带超时时间
唤醒 empty 阻塞线程让它去创建连接
这里进入等待状态,estimate 的值初始是 maxWait,由于是调用 awaitNanos 方法,所以每次被唤起 estimate 就会被刷新一次,根据 estimate 是否大于 0 来决定是否进行新一轮的获取连接,如果最终取不到则返回 null
testOnReturn
是否开启了 testOnReturn
rollback 回滚
empty.signal
testWhileIdle连接超出空闲时间是否测试连接有用
创建的连接对象为空
continue
takeLast
没有被 close
2.1.1.3: validationQueryCheck()
大于0,说明还有时间,继续循环
DruidAbstractDataSource
2.1.2: getConnectionDirect()
【初始化三大数组】1、connections = new DruidConnectionHolder[maxActive];2、evictConnections = new DruidConnectionHolder[maxActive];3、keepAliveConnections = new DruidConnectionHolder[maxActive];
removeAbandoned 是否开启
没有时间了
DruidPooledConnection.close()
init 方法的执行相当于是懒加载,以前在 new DruidDataSource() 就会 init,现在到真正使用的时候才会 init;init 的执行进行了锁的控制;
put 方法
连接不可用,丢弃
没超时
maxEvictableIdleTimeMillis
丢弃无用的连接,立刻获取有用的连接
1: new DruidDataSource()
getConnectionDirect【死循环获取】
是自动提交或者是只读
获取链接 - 2 - 池中取连接
testOnBorrow
2.1.1: init()
notEmpty.awaitNanos(estimate)
DestroyConnectionThread
CreateConnectionThread
keepAliveBetweenTimeMillis
从 activeConnections 移除改连接
【初始化 JDBC 参数】1、从 url 解读出数据库类型: JdbcUtils.getDbTypeRaw()2、从 url 解读出 driverClass: JdbcUtils.getDriverClassName()3、校验参数的合法性,比如:maxActive <= 0【初始化 MySqlExeceptionSorter】1、initExceptionStorter();不同数据库的异常处理不一样,可以自定义
开启了
2.1.1.4: 初始化三大数组()
destroyTask.run()
不带超时时间如果取不到一直阻塞到有连接
estimate 是否大于 0
notEmpty.await
disable = true
没有等待获取连接的线程
testConnectionInternal测试连接是否有用
不是自动提交并且不是只读
是否超时
init
putLast 放回池子
超出空闲时间,就检测
connections[poolingCount] = holder
收藏
0 条评论
下一页