This commit is contained in:
wenshao
2011-12-26 10:33:28 +08:00
parent 60a147de5e
commit ec09f1dbb5
10 changed files with 118 additions and 65 deletions
@@ -0,0 +1,17 @@
package com.alibaba.druid.pool.ha;
import com.alibaba.druid.pool.DruidDataSource;
public class DataSourceChangedEvent {
private final DruidDataSource dataSource;
public DataSourceChangedEvent(DruidDataSource dataSource){
this.dataSource = dataSource;
}
public DruidDataSource getDataSource() {
return dataSource;
}
}
@@ -9,6 +9,7 @@ import com.alibaba.druid.pool.DruidDataSource;
public class DataSourceHolder implements Closeable {
private final MultiDataSource multiDataSource;
private final DruidDataSource dataSource;
private boolean enable = true;
private final AtomicLong connectCount = new AtomicLong();
@@ -48,10 +49,11 @@ public class DataSourceHolder implements Closeable {
this.weightRegionEnd = weightReginEnd;
}
public DataSourceHolder(DruidDataSource dataSource){
public DataSourceHolder(MultiDataSource multiDataSource, DruidDataSource dataSource){
if (dataSource == null) {
throw new IllegalArgumentException("dataSource is null");
}
this.multiDataSource = multiDataSource;
this.dataSource = dataSource;
}
@@ -72,7 +74,11 @@ public class DataSourceHolder implements Closeable {
}
public void setEnable(boolean enable) {
this.enable = enable;
if (this.enable != enable) {
this.enable = enable;
multiDataSource.afterDataSourceChanged(null);
}
}
public boolean isFail() {
@@ -80,7 +86,10 @@ public class DataSourceHolder implements Closeable {
}
public void setFail(boolean fail) {
this.fail = fail;
if (this.fail != fail) {
this.fail = fail;
multiDataSource.afterDataSourceChanged(null);
}
}
public DruidDataSource getDataSource() {
@@ -24,11 +24,11 @@ public class HADataSource extends MultiDataSource implements HADataSourceMBean,
master.resetState();
slave.resetState();
}
public boolean isMasterWritable() {
return master != null && master.isWritable();
}
public boolean isSlaveWritable() {
return slave != null && slave.isWritable();
}
@@ -44,17 +44,17 @@ public class HADataSource extends MultiDataSource implements HADataSourceMBean,
public DataSourceHolder getMaster() {
return master;
}
public void restartMaster() {
this.restartDataSource("master");
}
public void restartSlave() {
this.restartDataSource("slave");
}
public DataSourceHolder setMaster(DruidDataSource master) {
DataSourceHolder holder = new DataSourceHolder(master);
DataSourceHolder holder = new DataSourceHolder(this, master);
this.setMaster(holder);
return holder;
}
@@ -69,7 +69,7 @@ public class HADataSource extends MultiDataSource implements HADataSourceMBean,
}
public DataSourceHolder setSlave(DruidDataSource slave) {
DataSourceHolder holder = new DataSourceHolder(slave);
DataSourceHolder holder = new DataSourceHolder(this, slave);
this.setSlave(holder);
return holder;
}
@@ -86,20 +86,20 @@ public class HADataSource extends MultiDataSource implements HADataSourceMBean,
return master.isEnable();
}
public boolean isMasterFail() {
if (master == null) {
return false;
}
return master.isFail();
}
public boolean isSlaveFail() {
if (slave == null) {
return false;
}
return slave.isFail();
}
@@ -109,8 +109,7 @@ public class HADataSource extends MultiDataSource implements HADataSourceMBean,
}
master.setEnable(value);
this.computeTotalWeight();
}
public String getMasterUrl() {
@@ -128,27 +127,27 @@ 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();
}
@@ -167,8 +166,6 @@ public class HADataSource extends MultiDataSource implements HADataSourceMBean,
}
slave.setEnable(value);
this.computeTotalWeight();
}
public void switchMasterSlave() {
@@ -31,7 +31,6 @@ import com.alibaba.druid.pool.ha.valid.DataSourceFailureDetecter;
import com.alibaba.druid.pool.ha.valid.DefaultDataSourceFailureDetecter;
import com.alibaba.druid.proxy.jdbc.DataSourceProxy;
import com.alibaba.druid.util.JdbcUtils;
import com.alibaba.druid.util.ThreadLocalRandom;
public class MultiDataSource extends DataSourceAdapter implements MultiDataSourceMBean, DataSourceProxy {
@@ -75,8 +74,6 @@ public class MultiDataSource extends DataSourceAdapter implements MultiDataSourc
private String name;
private int totalWeight = 0;
private ConfigLoader configLoader;
private int maxPoolSize = 50;
@@ -122,10 +119,6 @@ public class MultiDataSource extends DataSourceAdapter implements MultiDataSourc
this.configLoader = configLoader;
}
public int getTotalWeight() {
return totalWeight;
}
public String getName() {
if (name == null) {
return "HADataSource-" + System.identityHashCode(this);
@@ -176,6 +169,8 @@ public class MultiDataSource extends DataSourceAdapter implements MultiDataSourc
return;
}
this.balancer.init(this);
initInternal();
scheduler = Executors.newScheduledThreadPool(schedulerThreadCount);
@@ -259,7 +254,7 @@ public class MultiDataSource extends DataSourceAdapter implements MultiDataSourc
}
}
if (changeCount != 0) {
computeTotalWeight();
afterDataSourceChanged(null);
}
failureDetectCount.incrementAndGet();
@@ -304,7 +299,7 @@ public class MultiDataSource extends DataSourceAdapter implements MultiDataSourc
public void addDataSource(String name, DataSourceHolder dataSourceHolder) {
dataSources.put(name, dataSourceHolder);
this.computeTotalWeight();
afterDataSourceChanged(null);
}
public Properties getProperties() {
@@ -315,20 +310,7 @@ public class MultiDataSource extends DataSourceAdapter implements MultiDataSourc
return activeCount;
}
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.setWeightRegionEnd(totalWeight);
}
this.totalWeight = totalWeight;
public void notFailSignal() {
lock.lock();
try {
notFail.signalAll();
@@ -337,6 +319,10 @@ public class MultiDataSource extends DataSourceAdapter implements MultiDataSourc
}
}
public void afterDataSourceChanged(Object event) {
this.balancer.afterDataSourceChanged(null);
}
public Connection getConnection() throws SQLException {
init();
@@ -368,14 +354,6 @@ public class MultiDataSource extends DataSourceAdapter implements MultiDataSourc
}
}
public int produceRandomNumber() {
if (totalWeight == 0) {
return 0;
}
return ThreadLocalRandom.current().nextInt(totalWeight);
}
public MultiConnectionHolder getRealConnection(MultiDataSourceConnection multiConn, String sql) throws SQLException {
return balancer.getConnection(multiConn, sql);
}
@@ -24,8 +24,6 @@ public interface MultiDataSourceMBean {
long getBusySkipCount();
int getTotalWeight();
long getFailureDetectPeriodMillis();
long getConfigLoadPeriodMillis();
@@ -33,6 +31,4 @@ public interface MultiDataSourceMBean {
long getActiveCount();
int getMaxPoolSize();
int produceRandomNumber();
}
@@ -3,8 +3,11 @@ package com.alibaba.druid.pool.ha.balance;
import java.sql.SQLException;
import com.alibaba.druid.pool.ha.MultiConnectionHolder;
import com.alibaba.druid.pool.ha.MultiDataSource;
import com.alibaba.druid.pool.ha.MultiDataSourceConnection;
public interface Balancer {
void init(MultiDataSource dataSource);
void afterDataSourceChanged(Object event);
MultiConnectionHolder getConnection(MultiDataSourceConnection connectionProxy, String sql) throws SQLException;
}
@@ -16,9 +16,24 @@ public class RoundRobinBlancer implements Balancer {
private final AtomicInteger indexErrorCount = new AtomicInteger();
private MultiDataSource multiDataSource;
public RoundRobinBlancer(){
}
public void afterDataSourceChanged(Object event) {
}
@Override
public void init(MultiDataSource multiDataSource) {
this.multiDataSource = multiDataSource;
}
public MultiDataSource getMultiDataSource() {
return multiDataSource;
}
@Override
public MultiConnectionHolder getConnection(MultiDataSourceConnection connectionProxy, String sql)
@@ -46,18 +61,18 @@ public class RoundRobinBlancer implements Balancer {
if (!item.isEnable()) {
continue;
}
if (first == null) {
first = item;
}
if (itemIndex == index) {
dataSource = item;
break;
}
itemIndex++;
}
if (dataSource == null) {
dataSource = first;
}
@@ -8,9 +8,47 @@ import com.alibaba.druid.pool.ha.DataSourceHolder;
import com.alibaba.druid.pool.ha.MultiConnectionHolder;
import com.alibaba.druid.pool.ha.MultiDataSource;
import com.alibaba.druid.pool.ha.MultiDataSourceConnection;
import com.alibaba.druid.util.ThreadLocalRandom;
public class WeightBalancer implements Balancer {
private MultiDataSource multiDataSource;
private int totalWeight = 0;
@Override
public void init(MultiDataSource multiDataSource) {
this.multiDataSource = multiDataSource;
}
public void afterDataSourceChanged(Object event) {
computeTotalWeight();
}
public int produceRandomNumber() {
if (totalWeight == 0) {
return 0;
}
return ThreadLocalRandom.current().nextInt(totalWeight);
}
public void computeTotalWeight() {
int totalWeight = 0;
for (DataSourceHolder holder : multiDataSource.getDataSources().values()) {
if (!holder.isEnable()) {
holder.setWeightRegionBegin(-1);
holder.setWeightRegionEnd(-1);
continue;
}
holder.setWeightRegionBegin(totalWeight);
totalWeight += holder.getWeight();
holder.setWeightRegionEnd(totalWeight);
}
this.totalWeight = totalWeight;
multiDataSource.notFailSignal();
}
@Override
public MultiConnectionHolder getConnection(MultiDataSourceConnection connectionProxy, String sql)
throws SQLException {
@@ -27,7 +65,7 @@ public class WeightBalancer implements Balancer {
final int MAX_RETRY = 10;
for (int i = 0; i < MAX_RETRY; ++i) {
int randomNumber = multiDataSource.produceRandomNumber();
int randomNumber = produceRandomNumber();
DataSourceHolder first = null;
boolean needRetry = false;
@@ -96,7 +96,7 @@ public class CobarConfigLoader extends URLConnectionConfigLoader implements Conf
} else {
if (holder.getWeight() != weight) {
holder.setWeight(weight);
dataSource.computeTotalWeight();
dataSource.afterDataSourceChanged(null);
}
}
}
@@ -112,7 +112,7 @@ public class CobarConfigLoader extends URLConnectionConfigLoader implements Conf
}
}
if (removeCount != 0) {
dataSource.computeTotalWeight();
dataSource.afterDataSourceChanged(null);
}
}
@@ -143,7 +143,7 @@ public class CobarDataSource extends MultiDataSource {
}
dataSource.setProxyFilters(proxyFilters);
DataSourceHolder holder = new DataSourceHolder(dataSource);
DataSourceHolder holder = new DataSourceHolder(this, dataSource);
holder.setWeight(weight);
return holder;
}