
Druid连接池的connectionErrorRetryAttempts、 timeBetweenConnectErrorMillis、breakAfterAcquireFailure参数使用
Druid连接池的connectionErrorRetryAttempts、 timeBetweenConnectErrorMillis、breakAfterAcquireFailure参数使用
·
Druid连接池的connectionErrorRetryAttempts、
timeBetweenConnectErrorMillis、breakAfterAcquireFailure参数使用:
当获取连接时:
public DruidPooledConnection getConnection(long maxWaitMillis) throws SQLException {
init();
if (filters.size() > 0) {
FilterChainImpl filterChain = new FilterChainImpl(this);
return filterChain.dataSource_connect(this, maxWaitMillis);
} else {
return getConnectionDirect(maxWaitMillis);
}
}
其中的init():
private final CountDownLatch initedLatch = new CountDownLatch(2);
public void init() throws SQLException {
// inited初始值为false
if (inited) {
return;
}
// 此处跳过部分代码
......
try{
......
// 开启创建连接的线程
createAndStartCreatorThread();
// 开启销毁连接的线程
createAndStartDestroyThread();
// 初始化时为:new CountDownLatch(2);上述两个方法中会执行initedLatch.countDown
initedLatch.await();
......
}finally{
// 对 inited 进行更新,后续不再改为false,除非调用restart()方法
inited = true;
lock.unlock();
// 如果初始化成功,则打印初始化的日志:
LOG.info(msg);
}
}
// 进行初始化时,开启线程 createConnectionThread.start();
protected void createAndStartCreatorThread() {
if (createScheduler == null) {
String threadName = "Druid-ConnectionPool-Create-" + System.identityHashCode(this);
createConnectionThread = new CreateConnectionThread(threadName);
createConnectionThread.start();
return;
}
initedLatch.countDown();
}
public class CreateConnectionThread extends Thread {
public CreateConnectionThread(String name){
super(name);
this.setDaemon(true);
}
public void run() {
initedLatch.countDown();
long lastDiscardCount = 0;
int errorCount = 0;
// 死循环创建connection
for (;;) {
// addLast
......
try {
......
// 必须存在线程等待,才创建连接
......
// 防止创建超过maxActive数量的连接
......
PhysicalConnectionInfo connection = null;
try {
// 创建connection的方法
connection = createPhysicalConnection();
setFailContinuous(false);
} catch (SQLException e) {
LOG.error("create connection error, url: " + jdbcUrl + ", errorCode " + e.getErrorCode()
+ ", state " + e.getSQLState(), e);
errorCount++;
// 如果创建连接失败次数超过了配置项:connectionErrorRetryAttempts并且等待时间>0
if (errorCount > connectionErrorRetryAttempts && timeBetweenConnectErrorMillis > 0) {
// fail over retry attempts
......
// 查看配置项 breakAfterAcquireFailure
if (breakAfterAcquireFailure) {
break;
}
try {
// 根据配置进行睡眠
Thread.sleep(timeBetweenConnectErrorMillis);
} catch (InterruptedException interruptEx) {
break;
}
}
} catch (RuntimeException e) {
LOG.error("create connection error", e);
setFailContinuous(true);
continue;
} catch (Error e) {
LOG.error("create connection error", e);
setFailContinuous(true);
break;
}
if (connection == null) {
continue;
}
boolean result = put(connection);
if (!result) {
JdbcUtils.close(connection.getPhysicalConnection());
LOG.info("put physical connection to pool failed.");
}
errorCount = 0; // reset errorCount
}
}
}
CreateConnectionThread运行的线程,是一个死循环,一直进行创建连接,其中退出循环的相关配置项:
connectionErrorRetryAttempts: 创建连接失败重试次数
timeBetweenConnectErrorMillis:失败次数到达connectionErrorRetryAttempts值后,睡眠timeBetweenConnectErrorMillis时间,然后继续进行创建连接
breakAfterAcquireFailure:在进行睡眠之前,先查看该配置项是否为true,如果是,则退出死循环,此处会导致后续再也不进行创建连接(因为此处线程开启,仅在 createAndStartCreatorThread()方法中, 而该方法在 init() 方法中,在进行初始化时,有一个 inited 标志值,第一次进行初始化后,就将该值置为 true, 后续不再改为false,除非调用 restart()方法)
更多推荐
所有评论(0)