This commit is contained in:
wenshao
2011-12-26 09:53:18 +08:00
parent ba01e4fe8b
commit d38052d8eb
4 changed files with 41 additions and 112 deletions
@@ -25,6 +25,8 @@ import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.logging.Log;
import com.alibaba.druid.logging.LogFactory;
import com.alibaba.druid.pool.DataSourceAdapter;
import com.alibaba.druid.pool.ha.balance.Balancer;
import com.alibaba.druid.pool.ha.balance.WeightBalancer;
import com.alibaba.druid.pool.ha.config.ConfigLoader;
import com.alibaba.druid.pool.ha.valid.DataSourceFailureDetecter;
import com.alibaba.druid.pool.ha.valid.DefaultDataSourceFailureDetecter;
@@ -84,6 +86,8 @@ public class MultiDataSource extends DataSourceAdapter implements MultiDataSourc
private long activeCount = 0;
private long maxWaitMillis = 0;
private Balancer balancer = new WeightBalancer();
public long getMaxWaitMillis() {
return maxWaitMillis;
}
@@ -377,82 +381,7 @@ public class MultiDataSource extends DataSourceAdapter implements MultiDataSourc
}
public MultiConnectionHolder getRealConnection(MultiDataSourceConnection multiConn, String sql) throws SQLException {
long startNano = -1;
if (maxWaitMillis > 0) {
startNano = System.nanoTime();
}
DataSourceHolder dataSource = null;
final int MAX_RETRY = 10;
for (int i = 0; i < MAX_RETRY; ++i) {
int randomNumber = produceRandomNumber();
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 (needRetry) {
retryGetConnectionCount.incrementAndGet();
continue;
}
if (dataSource == null) {
dataSource = first;
}
if (dataSource == null && i != MAX_RETRY - 1) {
lock.lock();
try {
if (getEnabledDataSourceCount() == 0) {
try {
if (maxWaitMillis > 0) {
long nano = System.nanoTime() - startNano;
long restNano = maxWaitMillis * 1000 * 1000 - nano;
if (restNano > 0) {
notFail.awaitNanos(restNano);
} else {
break;
}
} else {
notFail.await();
}
continue;
} catch (InterruptedException e) {
throw new SQLException("interrupted", e);
}
}
} finally {
lock.unlock();
}
}
break;
}
if (dataSource == null) {
throw new SQLException("cannot get connection. enabledDataSourceCount " + getEnabledDataSourceCount());
}
return dataSource.getConnection();
return balancer.getConnection(multiConn, sql);
}
public int getEnabledDataSourceCount() {
@@ -471,15 +400,15 @@ public class MultiDataSource extends DataSourceAdapter implements MultiDataSourc
public long getRetryGetConnectionCount() {
return retryGetConnectionCount.get();
}
public void incrementRetryGetConnectionCount() {
retryGetConnectionCount.incrementAndGet();
}
public Lock getLock() {
return lock;
}
public Condition getNotFail() {
return notFail;
}
@@ -487,7 +416,7 @@ public class MultiDataSource extends DataSourceAdapter implements MultiDataSourc
public long getBusySkipCount() {
return busySkipCount.get();
}
public void incrementBusySkipCount() {
busySkipCount.incrementAndGet();
}
@@ -29,7 +29,7 @@ import com.alibaba.druid.proxy.jdbc.DataSourceProxy;
public class MultiDataSourceConnection extends WrapperAdapter implements Connection, ConnectionProxy {
private final MultiDataSource haDataSource;
private final MultiDataSource multiDataSource;
private Connection conn;
private DataSourceHolder dataSourceHolder;
@@ -51,8 +51,8 @@ public class MultiDataSourceConnection extends WrapperAdapter implements Connect
private boolean closed = false;
public MultiDataSourceConnection(MultiDataSource haDataSource, long id){
this.haDataSource = haDataSource;
public MultiDataSourceConnection(MultiDataSource multiDataSource, long id){
this.multiDataSource = multiDataSource;
this.id = id;
}
@@ -62,7 +62,7 @@ public class MultiDataSourceConnection extends WrapperAdapter implements Connect
public void checkConnection(String sql) throws SQLException {
if (conn == null) {
MultiConnectionHolder connHolder = haDataSource.getRealConnection(this, sql);
MultiConnectionHolder connHolder = multiDataSource.getRealConnection(this, sql);
conn = connHolder.getConnection();
this.dataSourceHolder = connHolder.getDataSourceHolder();
}
@@ -98,8 +98,8 @@ public class MultiDataSourceConnection extends WrapperAdapter implements Connect
connectedTime = new Date();
}
public MultiDataSource getHaDataSource() {
return haDataSource;
public MultiDataSource getMultiDataSource() {
return multiDataSource;
}
@Override
@@ -156,7 +156,7 @@ public class MultiDataSourceConnection extends WrapperAdapter implements Connect
}
this.closed = true;
haDataSource.afterConnectionClosed(this);
multiDataSource.afterConnectionClosed(this);
}
@Override
@@ -329,14 +329,14 @@ public class MultiDataSourceConnection extends WrapperAdapter implements Connect
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
long stmtId = haDataSource.createStatementId();
long stmtId = multiDataSource.createStatementId();
MultiDataSourceStatement stmt = new MultiDataSourceStatement(this, stmtId, resultSetType, resultSetConcurrency);
return stmt;
}
@Override
public Statement createStatement() throws SQLException {
long stmtId = haDataSource.createStatementId();
long stmtId = multiDataSource.createStatementId();
MultiDataSourceStatement stmt = new MultiDataSourceStatement(this, stmtId);
return stmt;
}
@@ -346,7 +346,7 @@ public class MultiDataSourceConnection extends WrapperAdapter implements Connect
checkConnection(sql);
PreparedStatement stmt = conn.prepareStatement(sql);
long stmtId = haDataSource.createStatementId();
long stmtId = multiDataSource.createStatementId();
return new MultiDataSourcePreparedStatement(this, stmt, sql, stmtId);
}
@@ -356,7 +356,7 @@ public class MultiDataSourceConnection extends WrapperAdapter implements Connect
checkConnection(sql);
CallableStatement stmt = conn.prepareCall(sql);
long stmtId = haDataSource.createStatementId();
long stmtId = multiDataSource.createStatementId();
return new CallableStatementProxyImpl(this, stmt, sql, stmtId);
}
@@ -367,7 +367,7 @@ public class MultiDataSourceConnection extends WrapperAdapter implements Connect
checkConnection(sql);
PreparedStatement stmt = conn.prepareStatement(sql, resultSetType, resultSetConcurrency);
long stmtId = haDataSource.createStatementId();
long stmtId = multiDataSource.createStatementId();
return new MultiDataSourcePreparedStatement(this, stmt, sql, stmtId);
}
@@ -377,7 +377,7 @@ public class MultiDataSourceConnection extends WrapperAdapter implements Connect
checkConnection(sql);
CallableStatement stmt = conn.prepareCall(sql, resultSetType, resultSetConcurrency);
long stmtId = haDataSource.createStatementId();
long stmtId = multiDataSource.createStatementId();
return new CallableStatementProxyImpl(this, stmt, sql, stmtId);
}
@@ -385,7 +385,7 @@ public class MultiDataSourceConnection extends WrapperAdapter implements Connect
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
throws SQLException {
long stmtId = haDataSource.createStatementId();
long stmtId = multiDataSource.createStatementId();
MultiDataSourceStatement stmt = new MultiDataSourceStatement(this, stmtId, resultSetType, resultSetConcurrency,
resultSetHoldability);
return stmt;
@@ -397,7 +397,7 @@ public class MultiDataSourceConnection extends WrapperAdapter implements Connect
checkConnection(sql);
PreparedStatement stmt = conn.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
long stmtId = haDataSource.createStatementId();
long stmtId = multiDataSource.createStatementId();
return new MultiDataSourcePreparedStatement(this, stmt, sql, stmtId);
}
@@ -408,7 +408,7 @@ public class MultiDataSourceConnection extends WrapperAdapter implements Connect
checkConnection(sql);
CallableStatement stmt = conn.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
long stmtId = haDataSource.createStatementId();
long stmtId = multiDataSource.createStatementId();
return new CallableStatementProxyImpl(this, stmt, sql, stmtId);
}
@@ -418,7 +418,7 @@ public class MultiDataSourceConnection extends WrapperAdapter implements Connect
checkConnection(sql);
PreparedStatement stmt = conn.prepareStatement(sql, autoGeneratedKeys);
long stmtId = haDataSource.createStatementId();
long stmtId = multiDataSource.createStatementId();
return new MultiDataSourcePreparedStatement(this, stmt, sql, stmtId);
}
@@ -428,7 +428,7 @@ public class MultiDataSourceConnection extends WrapperAdapter implements Connect
checkConnection(sql);
PreparedStatement stmt = conn.prepareStatement(sql, columnIndexes);
long stmtId = haDataSource.createStatementId();
long stmtId = multiDataSource.createStatementId();
return new MultiDataSourcePreparedStatement(this, stmt, sql, stmtId);
}
@@ -438,7 +438,7 @@ public class MultiDataSourceConnection extends WrapperAdapter implements Connect
checkConnection(sql);
PreparedStatement stmt = conn.prepareStatement(sql, columnNames);
long stmtId = haDataSource.createStatementId();
long stmtId = multiDataSource.createStatementId();
return new MultiDataSourcePreparedStatement(this, stmt, sql, stmtId);
}
@@ -578,12 +578,12 @@ public class MultiDataSourceConnection extends WrapperAdapter implements Connect
@Override
public Properties getProperties() {
return haDataSource.getProperties();
return multiDataSource.getProperties();
}
@Override
public DataSourceProxy getDirectDataSource() {
return haDataSource;
return multiDataSource;
}
@Override
@@ -23,7 +23,7 @@ public class RoundRobinBlancer implements Balancer {
@Override
public MultiConnectionHolder getConnection(MultiDataSourceConnection connectionProxy, String sql)
throws SQLException {
MultiDataSource multiDataSource = connectionProxy.getHaDataSource();
MultiDataSource multiDataSource = connectionProxy.getMultiDataSource();
int tryCount = 0;
@@ -14,9 +14,9 @@ public class WeightBalancer implements Balancer {
@Override
public MultiConnectionHolder getConnection(MultiDataSourceConnection connectionProxy, String sql)
throws SQLException {
MultiDataSource haDataSource = connectionProxy.getHaDataSource();
MultiDataSource multiDataSource = connectionProxy.getMultiDataSource();
long maxWaitMillis = haDataSource.getMaxWaitMillis();
long maxWaitMillis = multiDataSource.getMaxWaitMillis();
long startNano = -1;
if (maxWaitMillis > 0) {
@@ -27,11 +27,11 @@ public class WeightBalancer implements Balancer {
final int MAX_RETRY = 10;
for (int i = 0; i < MAX_RETRY; ++i) {
int randomNumber = haDataSource.produceRandomNumber();
int randomNumber = multiDataSource.produceRandomNumber();
DataSourceHolder first = null;
boolean needRetry = false;
for (DataSourceHolder item : haDataSource.getDataSources().values()) {
for (DataSourceHolder item : multiDataSource.getDataSources().values()) {
if (first == null) {
first = item;
}
@@ -42,7 +42,7 @@ public class WeightBalancer implements Balancer {
}
if (item.getDataSource().isBusy()) {
haDataSource.incrementBusySkipCount();
multiDataSource.incrementBusySkipCount();
needRetry = true;
break;
}
@@ -52,7 +52,7 @@ public class WeightBalancer implements Balancer {
}
if (needRetry) {
haDataSource.incrementRetryGetConnectionCount();
multiDataSource.incrementRetryGetConnectionCount();
continue;
}
@@ -61,11 +61,11 @@ public class WeightBalancer implements Balancer {
}
if (dataSource == null && i != MAX_RETRY - 1) {
Lock lock = haDataSource.getLock();
Condition notFail = haDataSource.getNotFail();
Lock lock = multiDataSource.getLock();
Condition notFail = multiDataSource.getNotFail();
lock.lock();
try {
if (haDataSource.getEnabledDataSourceCount() == 0) {
if (multiDataSource.getEnabledDataSourceCount() == 0) {
try {
if (maxWaitMillis > 0) {
long nano = System.nanoTime() - startNano;
@@ -91,7 +91,7 @@ public class WeightBalancer implements Balancer {
}
if (dataSource == null) {
throw new SQLException("cannot get connection. enabledDataSourceCount " + haDataSource.getEnabledDataSourceCount());
throw new SQLException("cannot get connection. enabledDataSourceCount " + multiDataSource.getEnabledDataSourceCount());
}
return dataSource.getConnection();