Open TianEx opened 5 years ago
每次获取connection都会调用init,内部使用inited标识DataSource是否已经初始化:
PS:获取程序的调用栈,标注由哪个函数调用的init方法 从SPI中加载Filter,如果前面加载的filter不存在则还需要进行初始化 initedLatch用于等待之前的线程初始化完成 如果keepAlive为true并且createScheduler不为空,则初始化minIdle个线程用于创建连接
DestroyConnectionThread线程会定期执行一次清理动作,可以指定timeBetweenEvictionRunsMillis控制清理的频率, 主要逻辑在DestroyTask,首先会执行shrink对过期时间进行处理,然后根据removeAbandoned的值判断是否需要清理abandoned连接,shrink只针对连接池的连接进行清理,而removeAbandoned会对从连接池外的连接进行清理。
shrink只会清理连接池内的连接,有几个参数需要注意下: phyTimeoutMillis:连接最大存活时间,默认是-1(不限制物理连接时间),从创建连接开始计算如果超过该时间则会被清理 keepAlive:默认是false,标记连接池内的连接是否需要保持存活,如果设为true的话,则会每次清理的时候,都会调用validateConnection,针对mysql而言就会往db发ping维持连接;这和前面提到的testOnBorrow、testWhileIdle类似 lastActiveTimeMillis:上次active的时间,在连接被recycle或者清理线程在清理时会重新标记该时间,需指定keepAlive为true minEvictableIdleTimeMillis:默认1800000ms,如果上次active时间lastActiveTimeMillis至当前时刻,如果小于该时间,则不进行清理 maxEvictableIdleTimeMillis:默认25200000ms,如果超过了maxEvictableIdleTimeMillis则该连接会被清理掉
shrink对时间的处理比较复杂,下面基于checkTime为true的情况进行分析: 如果是指定了phyTimeoutMillis,并且创建时间大于该值,则直接回收 如果上次active时间小于minEvictableIdleTimeMillis则不进行处理 如果上次active时间小于minEvictableIdleTimeMillis则清理掉checkCount个连接(需要维持在minIdle个连接) 如果超过了maxEvictableIdleTimeMillis直接清理 如果介于minEvictableIdleTimeMillis和maxEvictableIdleTimeMillis之间,并且keepAlive是true,则需要keepAlive
锁 -> 多线程create/destroy/get操作连接,所以操作线程需要获取锁才可以对内部数据进行操作 如果使用公平锁,应用调用getConnection是根据请求的先后顺序依次获取connection,非公平锁则允许抢占 notEmpty -> 如果获取连接的线程发现pool空,一方面会signal empty,另一方面自己会调用notEmpty#await进行等待,由 CreateConnectionThread唤醒,或其他线程释放连接时唤醒 empty -> CreateConnectionThread只有在连接池不够用的情况下才会创建,否则调用empty#await挂起线程
初始化
每次获取connection都会调用init,内部使用inited标识DataSource是否已经初始化:
PS:获取程序的调用栈,标注由哪个函数调用的init方法 从SPI中加载Filter,如果前面加载的filter不存在则还需要进行初始化 initedLatch用于等待之前的线程初始化完成 如果keepAlive为true并且createScheduler不为空,则初始化minIdle个线程用于创建连接
获取连接
DestroyConnectionThread线程会定期执行一次清理动作,可以指定timeBetweenEvictionRunsMillis控制清理的频率, 主要逻辑在DestroyTask,首先会执行shrink对过期时间进行处理,然后根据removeAbandoned的值判断是否需要清理abandoned连接,shrink只针对连接池的连接进行清理,而removeAbandoned会对从连接池外的连接进行清理。
shrink只会清理连接池内的连接,有几个参数需要注意下: phyTimeoutMillis:连接最大存活时间,默认是-1(不限制物理连接时间),从创建连接开始计算如果超过该时间则会被清理 keepAlive:默认是false,标记连接池内的连接是否需要保持存活,如果设为true的话,则会每次清理的时候,都会调用validateConnection,针对mysql而言就会往db发ping维持连接;这和前面提到的testOnBorrow、testWhileIdle类似 lastActiveTimeMillis:上次active的时间,在连接被recycle或者清理线程在清理时会重新标记该时间,需指定keepAlive为true minEvictableIdleTimeMillis:默认1800000ms,如果上次active时间lastActiveTimeMillis至当前时刻,如果小于该时间,则不进行清理 maxEvictableIdleTimeMillis:默认25200000ms,如果超过了maxEvictableIdleTimeMillis则该连接会被清理掉
shrink对时间的处理比较复杂,下面基于checkTime为true的情况进行分析: 如果是指定了phyTimeoutMillis,并且创建时间大于该值,则直接回收 如果上次active时间小于minEvictableIdleTimeMillis则不进行处理 如果上次active时间小于minEvictableIdleTimeMillis则清理掉checkCount个连接(需要维持在minIdle个连接) 如果超过了maxEvictableIdleTimeMillis直接清理 如果介于minEvictableIdleTimeMillis和maxEvictableIdleTimeMillis之间,并且keepAlive是true,则需要keepAlive
锁 -> 多线程create/destroy/get操作连接,所以操作线程需要获取锁才可以对内部数据进行操作 如果使用公平锁,应用调用getConnection是根据请求的先后顺序依次获取connection,非公平锁则允许抢占 notEmpty -> 如果获取连接的线程发现pool空,一方面会signal empty,另一方面自己会调用notEmpty#await进行等待,由 CreateConnectionThread唤醒,或其他线程释放连接时唤醒 empty -> CreateConnectionThread只有在连接池不够用的情况下才会创建,否则调用empty#await挂起线程