mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
Optimize the logic in HA Validation.
This commit is contained in:
+22
-1
@@ -31,7 +31,8 @@ import java.sql.Connection;
|
||||
public class RandomDataSourceRecoverThread implements Runnable {
|
||||
private final static Log LOG = LogFactory.getLog(RandomDataSourceRecoverThread.class);
|
||||
private RandomDataSourceSelector selector;
|
||||
private int sleepSeconds = 30;
|
||||
private int sleepSeconds = 60;
|
||||
private int validationSleepSeconds = 0;
|
||||
|
||||
public RandomDataSourceRecoverThread(RandomDataSourceSelector selector) {
|
||||
this.selector = selector;
|
||||
@@ -61,6 +62,7 @@ public class RandomDataSourceRecoverThread implements Runnable {
|
||||
Connection connection = null;
|
||||
try {
|
||||
connection = dataSource.getConnection();
|
||||
sleepBeforeValidation();
|
||||
dataSource.validateConnection(connection);
|
||||
LOG.info(dataSource.getName() + " is available now.");
|
||||
selector.removeBlacklist(dataSource);
|
||||
@@ -75,6 +77,17 @@ public class RandomDataSourceRecoverThread implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
private void sleepBeforeValidation() {
|
||||
if (validationSleepSeconds > 0) {
|
||||
try {
|
||||
LOG.debug("Sleep " + validationSleepSeconds + " second(s) before validation.");
|
||||
Thread.sleep(validationSleepSeconds * 1000);
|
||||
} catch (InterruptedException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sleep() {
|
||||
try {
|
||||
Thread.sleep(sleepSeconds * 1000);
|
||||
@@ -90,4 +103,12 @@ public class RandomDataSourceRecoverThread implements Runnable {
|
||||
public void setSleepSeconds(int sleepSeconds) {
|
||||
this.sleepSeconds = sleepSeconds;
|
||||
}
|
||||
|
||||
public int getValidationSleepSeconds() {
|
||||
return validationSleepSeconds;
|
||||
}
|
||||
|
||||
public void setValidationSleepSeconds(int validationSleepSeconds) {
|
||||
this.validationSleepSeconds = validationSleepSeconds;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public class RandomDataSourceSelector implements DataSourceSelector {
|
||||
private RandomDataSourceRecoverThread recoverThread;
|
||||
|
||||
private int checkingIntervalSeconds = 15;
|
||||
private int recoveryIntervalSeconds = 30;
|
||||
private int recoveryIntervalSeconds = 60;
|
||||
private int validationSleepSeconds = 0;
|
||||
private int blacklistThreshold = 3;
|
||||
|
||||
@@ -118,6 +118,10 @@ public class RandomDataSourceSelector implements DataSourceSelector {
|
||||
return blacklist;
|
||||
}
|
||||
|
||||
public boolean containInBlacklist(DataSource dataSource) {
|
||||
return dataSource != null && blacklist.contains(dataSource);
|
||||
}
|
||||
|
||||
public void addBlacklist(DataSource dataSource) {
|
||||
if (dataSource != null && !blacklist.contains(dataSource)) {
|
||||
blacklist.add(dataSource);
|
||||
@@ -128,7 +132,7 @@ public class RandomDataSourceSelector implements DataSourceSelector {
|
||||
}
|
||||
|
||||
public void removeBlacklist(DataSource dataSource) {
|
||||
if (dataSource != null && blacklist.contains(dataSource)) {
|
||||
if (containInBlacklist(dataSource)) {
|
||||
blacklist.remove(dataSource);
|
||||
if (dataSource instanceof DruidDataSource) {
|
||||
((DruidDataSource) dataSource).setTestOnReturn(highAvailableDataSource.isTestOnReturn());
|
||||
@@ -161,14 +165,19 @@ public class RandomDataSourceSelector implements DataSourceSelector {
|
||||
}
|
||||
|
||||
private void initThreads() {
|
||||
validateThread = new RandomDataSourceValidateThread(this);
|
||||
validateThread.setCheckingIntervalSeconds(checkingIntervalSeconds);
|
||||
validateThread.setValidationSleepSeconds(validationSleepSeconds);
|
||||
validateThread.setBlacklistThreshold(blacklistThreshold);
|
||||
new Thread(validateThread, "RandomDataSourceSelector-isValid-thread").start();
|
||||
if (validateThread == null) {
|
||||
validateThread = new RandomDataSourceValidateThread(this);
|
||||
validateThread.setCheckingIntervalSeconds(checkingIntervalSeconds);
|
||||
validateThread.setValidationSleepSeconds(validationSleepSeconds);
|
||||
validateThread.setBlacklistThreshold(blacklistThreshold);
|
||||
}
|
||||
new Thread(validateThread, "RandomDataSourceSelector-validate-thread").start();
|
||||
|
||||
recoverThread = new RandomDataSourceRecoverThread(this);
|
||||
recoverThread.setSleepSeconds(recoveryIntervalSeconds);
|
||||
if (recoverThread == null) {
|
||||
recoverThread = new RandomDataSourceRecoverThread(this);
|
||||
recoverThread.setSleepSeconds(recoveryIntervalSeconds);
|
||||
recoverThread.setValidationSleepSeconds(validationSleepSeconds);
|
||||
}
|
||||
new Thread(recoverThread, "RandomDataSourceSelector-recover-thread").start();
|
||||
}
|
||||
|
||||
|
||||
+7
-1
@@ -89,7 +89,8 @@ public class RandomDataSourceValidateThread implements Runnable {
|
||||
for (Map.Entry<String, Integer> e : errorCounts.entrySet()) {
|
||||
if (e.getValue() <= 0) {
|
||||
selector.removeBlacklist(dataSourceMap.get(e.getKey()));
|
||||
} else if (e.getValue() >= blacklistThreshold) {
|
||||
} else if (e.getValue() >= blacklistThreshold
|
||||
&& !selector.containInBlacklist(dataSourceMap.get(e.getKey()))) {
|
||||
LOG.warn("Adding " + e.getKey() + " to blacklist.");
|
||||
selector.addBlacklist(dataSourceMap.get(e.getKey()));
|
||||
}
|
||||
@@ -105,6 +106,11 @@ public class RandomDataSourceValidateThread implements Runnable {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (selector.containInBlacklist(e.getValue())) {
|
||||
LOG.debug(e.getKey() + " is already in blacklist, skip.");
|
||||
continue;
|
||||
}
|
||||
|
||||
tasks.add(new Callable<Boolean>() {
|
||||
@Override
|
||||
public Boolean call() {
|
||||
|
||||
@@ -40,6 +40,7 @@ public class RandomDataSourceSelectorTest extends BaseRandomDataSourceSelectorTe
|
||||
|
||||
assertEquals(10, selector.getValidationSleepSeconds());
|
||||
assertEquals(10, selector.getValidateThread().getValidationSleepSeconds());
|
||||
assertEquals(10, selector.getRecoverThread().getValidationSleepSeconds());
|
||||
|
||||
assertEquals(5, selector.getBlacklistThreshold());
|
||||
assertEquals(5, selector.getValidateThread().getBlacklistThreshold());
|
||||
|
||||
+2
-2
@@ -31,13 +31,13 @@ public class RandomDataSourceSelectorWithValidationTest {
|
||||
@Test
|
||||
public void testOneDataSourceFailAndRecover() throws Exception {
|
||||
RandomDataSourceSelector selector = ((RandomDataSourceSelector) highAvailableDataSource.getDataSourceSelector());
|
||||
selector.setCheckingIntervalSeconds(3);
|
||||
selector.getValidateThread().setCheckingIntervalSeconds(3);
|
||||
selector.getRecoverThread().setSleepSeconds(3);
|
||||
selector.init();
|
||||
|
||||
DruidDataSource dataSource = (DruidDataSource) highAvailableDataSource.getDataSourceMap().get("foo");
|
||||
dataSource.setValidationQuery("select xxx from yyy");
|
||||
Thread.sleep(6 * 1000);
|
||||
Thread.sleep(10 * 1000);
|
||||
assertTrue(dataSource.isTestOnReturn());
|
||||
for (int i = 0; i < 100; i++) {
|
||||
assertNotEquals(dataSource, selector.get());
|
||||
|
||||
Reference in New Issue
Block a user