この記事は「新人クリエーションセレモニー」活動に参加し、一緒にナゲットクリエーションの道を歩み始めました
getConnectionソースコードで導入されたDruidのremoveAbandonedメカニズムがあります。removeAbandonedは、実際にはDruidのリーク検出メカニズムです。主なパラメータは次のとおりです。
パラメータ | 説明する |
---|---|
removeAbandoned | 接続がリークした場合、リークした接続をリサイクルするかどうかにかかわらず、デフォルトはfalseです。 |
logAbandoned | リークされた接続がリサイクルされる場合、ログを印刷するかどうかにかかわらず、デフォルトはfalseです。 |
removeAbandonedTimeoutMillis | 接続のリサイクルのタイムアウト。デフォルトは5分です。 |
removeAbandonedは、接続リーク検出メカニズムを有効にするためのスイッチとして使用されます。デフォルト値はfalseです。trueの場合、DestroyTask呼び出しの頻度で定期的に検出されます。DestroyTaskのrunメソッドで:
@Override
public void run() {
shrink(true, keepAlive);
if (isRemoveAbandoned()) {
removeAbandoned();
}
}
复制代码
接続リーク検出メカニズムが有効になっている場合、接続がタイムアウト期間をトリガーするかどうかを定期的に検出し、トリガーされると接続が閉じられます。get後に使用されるすべての接続は、activeConnectionsに配置されます。次に、activeConnectionsをトラバースし、接続を判断し、タイムアウトがトリガーされた場合は閉じます。removeAbandonedのソースコードは次のとおりです。
//定义一个abandonedList来存放符合超时时间的连接。
List<DruidPooledConnection> abandonedList = new ArrayList<DruidPooledConnection>();
//加锁
activeConnectionLock.lock();
try {
//通过迭代器遍历activeConnections
Iterator<DruidPooledConnection> iter = activeConnections.keySet().iterator();
for (; iter.hasNext();) {
//获取到连接
DruidPooledConnection pooledConnection = iter.next();
//如果连级为Running状态,说明sql语句正在执行,则跳过当前连接
if (pooledConnection.isRunning()) {
continue;
}
//计算超时时间 默认值为5分钟
long timeMillis = (currrentNanos - pooledConnection.getConnectedTimeNano()) / (1000 * 1000);
//如果触发超时:
if (timeMillis >= removeAbandonedTimeoutMillis) {
//从iter删除该连接
iter.remove();
//关闭setTraceEnable
pooledConnection.setTraceEnable(false);
//添加到abandonedList
abandonedList.add(pooledConnection);
}
}
} finally {
//解锁
activeConnectionLock.unlock();
}
复制代码
タイムアウト条件を満たす接続をabandonedListに配置します。abandonedListが空でない場合は、abandonedListを繰り返し処理し、接続を閉じます。
//定义锁
final ReentrantLock lock = pooledConnection.lock;
lock.lock();
try {
//如果连接为disiable状态 说明已经不可用 直接跳过
if (pooledConnection.isDisable()) {
continue;
}
} finally {
//解锁
lock.unlock();
}
//关闭连接
JdbcUtils.close(pooledConnection);
//设置abandond状态
pooledConnection.abandond();
//增加计数器
removeAbandonedCount++;
removeCount++;
复制代码
その後、ログ処理が実行されます。警告ログを出力した後、メソッドが実行されます。