聊聊Druid(三) -- 连接的销毁,连接泄露检测与重用

为什么80%的码农都做不了架构师?>>>   hot3.png

连接流转

              聊聊Druid(三) -- 连接的销毁,连接泄露检测与重用_第1张图片

 

Druid的连接回收是交给DestroyTask处理的。连接检测间隔可以通过timeBetweenEvictionRunsMillis进行配置,默认是60s。DestoryTask的核心功能有两个:shrink和removeAbandoned。

关键属性

属性名称

所属类

描述

poolingCount

DruidDataSource

当前连接池可用数量

activeCount        

DruidDataSource

被使用中的连接数量

minIdle

DruidDataSource

最小空闲时间

minEvictableIdleTimeMillis

DruidDataSource

   

maxEvictableIdleTimeMillis

DruidDataSource

 

connectTimeMillis

DruidConnectionHolder

物理连接创建时间

phyTimeoutMillis

DruidDataSource

物理连接超时时间

lastActiveTimeMillis

DruidConnectionHolder

最新活跃时间。刷新时机:

1、执行完sql之后就会更新。

比如executeQuery中调用afterExecute方法

2、keepAlive检查通过之后刷新

3、初始化。创建物理连接时:

lastActiveTimeMillis = connectTimeMillis = = System.currentTimeMillis()

keepAliveCheckCount

DruidConnectionHolder

用于统计计数。在shrink中,对连接进行keepAlive检查的时候就会递增

testOnReturn

DruidDataSource

 

testOnBorrow

DruidDataSource

 

testWhileIdle

DruidDataSource

 

removeAbandoned

DruidDataSource

是否移除已经被丢弃的连接。其实是连接泄露检测。当连接已经被丢弃,但又未关闭释放时,会造成连接

泄露。使用这个状态可以在获取连接的时候,将连接放入到activeConnections中。在destroyTask中会执行

removeAbandoned方法,对activeConnections中的连接进行连接泄露检测。

开启该属性会损失一部分性能。

traceEnable

DruidPooledConnection

被removeAbandoned的连接设置为false。

disable

DruidPooledConnection

被removeAbandoned的连接设置为false。

shrink

该方法在DestroyThread中执行,主要作用是用于对连接进行检测,丢弃和关闭检测不通过的连接,调整连接池。

  • 获取需要检测连接的数量:checkCount = poolingCount - minIdle;
  • 是否设置了物理连接的超时时间phyTimoutMills。假如设置了该时间,判断连接时间存活时间是否已经超过phyTimeoutMills,是则放入evictConnections中。
  • 空余时间大于minEvictableIdleTimeMillis,并且索引(在连接池中的index)小于checkCount的连接则放入evictConnections;空余时间小于minEvictableIdleTimeMillis的不需要回收
  • 空余时间大于minEvictableIdleTimeMillis,并且索引大于checkCount的连接,假若空余时间大于maxEvictableIdleTimeMillis则放入evictConnections,否则放入keepAliveConnections中进行keepAlive检测。

evictConnections中的连接会从connections中移除,并且使用JdbcUtils.close()  关闭连接

对keepAliveConnections中的连接进行连接可用性检测(validateConnection方法进行检查,创建物理连接后也是使用该方法检查连接)。检测通过之后,继续使用该连接(采用的是先移除,检测通过再放入的方式),否则使用JdbcUtils.close()  关闭连接。

由于获取连接后,会将连接从connections中移除:

decrementPoolingCount();

DruidConnectionHolder  last=connections[poolingCount];

connections[poolingCount]=null;

当连接使用完之后,在recycle时会检查连接是否还可用(testOnReturn  -- 其实这些属性都是体现了数据库连接池的设计和连接的生命阶段。),假如可用的话会刷新lastActiveTimeMillis后放入到connections中(放在尾部,符合尾部最新的原则)

整个连接创建最关键的就是连接在connections中的管理,包括新插入,移除和重新插入。  涉及createTimeMills和lastActiveTimeMillis。这个一定要搞清楚,创建连接时是怎么放进去,shrink时怎么移除,怎么判断,使用完连接之后又是怎么recycle,recycle的时候又是改变了哪些相关的值。

 

removeAbandoned

连接泄露检测。通过removeAbandoned属性配置是否打开连接泄露检测。

  1. 获取activeConnectionLock
  2. 判断连接是否在使用中。pooledConnection.isRunning()
  3. 连接创建时间是否大于removeAbandonedTimeoutMillis,否则结束处理
  4. 设置traceEnable为false
  5. 将连接从activeConnections中移除
  6. 释放activeConnectionLock
  7. 标记pooledConnection为disable(需要获取DruidPooledConnection的lock)
  8. 关闭连接
  9. 标记为abandoned
  10. removeAbandonedCount++

开启连接泄露功能会带来一定的性能影响,建议在需要排查问题时才打开次功能

转载于:https://my.oschina.net/everxu/blog/1632048

你可能感兴趣的:(聊聊Druid(三) -- 连接的销毁,连接泄露检测与重用)