This commit is contained in:
wenshao
2011-12-21 13:19:23 +08:00
parent bdba952244
commit 63ae20662e
7 changed files with 116 additions and 22 deletions
@@ -806,6 +806,15 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
lock.unlock();
}
}
public boolean isBusy() {
lock.lock();
try {
return this.inited && this.activeCount == maxActive && this.poolingCount == 0;
} finally {
lock.unlock();
}
}
public long getRemoveAbandonedCount() {
return removeAbandonedCount;
@@ -20,7 +20,7 @@ public class DataSourceHolder implements Closeable {
private transient int weightRegionBegin;
private transient int weightReginEnd;
private transient int weightRegionEnd;
public int getWeightRegionBegin() {
return weightRegionBegin;
@@ -30,12 +30,12 @@ public class DataSourceHolder implements Closeable {
this.weightRegionBegin = weightRegionBegin;
}
public int getWeightReginEnd() {
return weightReginEnd;
public int getWeightRegionEnd() {
return weightRegionEnd;
}
public void setWeightReginEnd(int weightReginEnd) {
this.weightReginEnd = weightReginEnd;
public void setWeightRegionEnd(int weightReginEnd) {
this.weightRegionEnd = weightReginEnd;
}
public DataSourceHolder(DruidDataSource dataSource){
@@ -114,6 +114,30 @@ public class HADataSource extends MultiDataSource implements HADataSourceMBean,
return slave.getUrl();
}
public int getMasterWeight() {
return master.getWeight();
}
public int getSlaveWeight() {
return slave.getWeight();
}
public int getMasterWeightRegionBegin() {
return master.getWeightRegionBegin();
}
public int getMasterWeightRegionEnd() {
return master.getWeightRegionEnd();
}
public int getSlaveWeightRegionBegin() {
return slave.getWeightRegionBegin();
}
public int getSlaveWeightRegionEnd() {
return slave.getWeightRegionEnd();
}
public boolean isSlaveEnable() {
if (slave == null) {
@@ -28,4 +28,16 @@ public interface HADataSourceMBean extends MultiDataSourceMBean {
boolean isMasterFail();
boolean isSlaveFail();
int getMasterWeight();
int getSlaveWeight();
int getMasterWeightRegionBegin();
int getMasterWeightRegionEnd();
int getSlaveWeightRegionBegin();
int getSlaveWeightRegionEnd();
}
@@ -44,6 +44,9 @@ public abstract class MultiDataSource extends DataSourceAdapter implements Multi
private final AtomicLong configLoadCount = new AtomicLong();
private final AtomicLong failureDetectCount = new AtomicLong();
private final AtomicLong busySkipCount = new AtomicLong();
private final AtomicLong retryGetConnectionCount = new AtomicLong();
protected DataSourceFailureDetecter validDataSourceChecker = new DefaultDataSourceFailureDetecter();
private long failureDetectPeriodMillis = 3000;
private long configLoadPeriodMillis = 1000 * 60;
@@ -209,14 +212,18 @@ public abstract class MultiDataSource extends DataSourceAdapter implements Multi
}
public void failureDetect() {
int changeCount = 0;
for (DataSourceHolder dataSourceHolder : getDataSources().values()) {
boolean isValid = validDataSourceChecker.isValid(dataSourceHolder.getDataSource());
if (!isValid) {
dataSourceHolder.setFail(true);
} else {
dataSourceHolder.setFail(false);
boolean isFail = !validDataSourceChecker.isValid(dataSourceHolder.getDataSource());
if (isFail != dataSourceHolder.isFail()) {
dataSourceHolder.setFail(isFail);
changeCount++;
}
}
if (changeCount != 0) {
computeTotalWeight();
}
}
protected ScheduledExecutorService getScheduler() {
@@ -268,9 +275,14 @@ public abstract class MultiDataSource extends DataSourceAdapter implements Multi
public void computeTotalWeight() {
int totalWeight = 0;
for (DataSourceHolder holder : this.dataSources.values()) {
if (!holder.isEnable()) {
holder.setWeightRegionBegin(-1);
holder.setWeightRegionEnd(-1);
continue;
}
holder.setWeightRegionBegin(totalWeight);
totalWeight += holder.getWeight();
holder.setWeightReginEnd(totalWeight);
holder.setWeightRegionEnd(totalWeight);
}
this.totalWeight = totalWeight;
}
@@ -283,21 +295,44 @@ public abstract class MultiDataSource extends DataSourceAdapter implements Multi
public MultiConnectionHolder getConnectionInternal(MultiDataSourceConnection multiConn, String sql)
throws SQLException {
int randomNumber = random.nextInt(totalWeight);
DataSourceHolder dataSource = null;
DataSourceHolder first = null;
for (DataSourceHolder item : this.dataSources.values()) {
if (first == null) {
first = item;
final int MAX_RETRY = 10;
for (int i = 0; i < MAX_RETRY; ++i) {
int randomNumber = random.nextInt(totalWeight);
DataSourceHolder first = null;
boolean needRetry = false;
for (DataSourceHolder item : this.dataSources.values()) {
if (first == null) {
first = item;
}
if (randomNumber >= item.getWeightRegionBegin() && randomNumber < item.getWeightRegionEnd()) {
if (!item.isEnable()) {
needRetry = true;
break;
}
if (item.getDataSource().isBusy()) {
busySkipCount.incrementAndGet();
needRetry = true;
break;
}
dataSource = item;
}
}
if (randomNumber >= item.getWeightRegionBegin() && randomNumber < item.getWeightReginEnd()) {
dataSource = item;
if (needRetry) {
retryGetConnectionCount.incrementAndGet();
continue;
}
}
if (dataSource == null) {
dataSource = first;
if (dataSource == null) {
dataSource = first;
}
break;
}
return dataSource.getConnection();
@@ -305,6 +340,14 @@ public abstract class MultiDataSource extends DataSourceAdapter implements Multi
public void handleNotAwailableDatasource(DataSourceHolder dataSourceHolder) {
}
public long getRetryGetConnectionCount() {
return retryGetConnectionCount.get();
}
public long getBusySkipCount() {
return busySkipCount.get();
}
public String[] getDataSourceNames() {
return this.dataSources.keySet().toArray(new String[this.dataSources.size()]);
@@ -358,7 +401,7 @@ public abstract class MultiDataSource extends DataSourceAdapter implements Multi
public long getConfigLoadCount() {
return configLoadCount.get();
}
public long getFailureDetectCount() {
return failureDetectCount.get();
}
@@ -19,4 +19,8 @@ public interface MultiDataSourceMBean {
long getConfigLoadCount();
long getFailureDetectCount();
long getRetryGetConnectionCount();
long getBusySkipCount();
}
@@ -76,6 +76,8 @@ public class CobarDataSource extends MultiDataSource {
if (CobarConfigLoader.isCobar(url)) {
this.setConfigLoader(new CobarConfigLoader(this));
this.getConfigLoader().load();
} else {
DataSourceHolder holder = createDataSourceHolder(this.url, 1);
this.addDataSource("master", holder);