mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
ha
This commit is contained in:
@@ -18,6 +18,26 @@ public class DataSourceHolder implements Closeable {
|
||||
|
||||
private int weight = 1;
|
||||
|
||||
private transient int weightRegionBegin;
|
||||
|
||||
private transient int weightReginEnd;
|
||||
|
||||
public int getWeightRegionBegin() {
|
||||
return weightRegionBegin;
|
||||
}
|
||||
|
||||
public void setWeightRegionBegin(int weightRegionBegin) {
|
||||
this.weightRegionBegin = weightRegionBegin;
|
||||
}
|
||||
|
||||
public int getWeightReginEnd() {
|
||||
return weightReginEnd;
|
||||
}
|
||||
|
||||
public void setWeightReginEnd(int weightReginEnd) {
|
||||
this.weightReginEnd = weightReginEnd;
|
||||
}
|
||||
|
||||
public DataSourceHolder(DruidDataSource dataSource){
|
||||
if (dataSource == null) {
|
||||
throw new IllegalArgumentException("dataSource is null");
|
||||
@@ -69,10 +89,12 @@ public class DataSourceHolder implements Closeable {
|
||||
return dataSource.getUrl();
|
||||
}
|
||||
|
||||
public Connection getConnection() throws SQLException {
|
||||
public MultiConnectionHolder getConnection() throws SQLException {
|
||||
connectCount.incrementAndGet();
|
||||
try {
|
||||
return dataSource.getConnection();
|
||||
Connection conn = dataSource.getConnection();
|
||||
|
||||
return new MultiConnectionHolder(this, conn);
|
||||
} catch (SQLException ex) {
|
||||
connectErrorCount.incrementAndGet();
|
||||
throw ex;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.alibaba.druid.pool.ha;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
@@ -146,23 +145,20 @@ public class HADataSource extends MultiDataSource implements HADataSourceMBean,
|
||||
}
|
||||
|
||||
public MultiConnectionHolder getConnectionInternal(MultiDataSourceConnection connection, String sql) throws SQLException {
|
||||
Connection conn = null;
|
||||
DataSourceHolder dataSource = null;
|
||||
if (master.isEnable()) {
|
||||
dataSource = master;
|
||||
conn = master.getConnection();
|
||||
}
|
||||
|
||||
if (conn == null && slave.isEnable()) {
|
||||
if (dataSource == null && slave.isEnable()) {
|
||||
dataSource = slave;
|
||||
conn = slave.getConnection();
|
||||
}
|
||||
|
||||
if (conn == null) {
|
||||
if (dataSource == null) {
|
||||
throw new SQLException("get HAConnection error");
|
||||
}
|
||||
|
||||
return new MultiConnectionHolder(dataSource, conn);
|
||||
return dataSource.getConnection();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
|
||||
@@ -7,6 +7,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.Executors;
|
||||
@@ -54,10 +55,13 @@ public abstract class MultiDataSource extends DataSourceAdapter implements Multi
|
||||
|
||||
private String name;
|
||||
|
||||
private long totalWeight = 0;
|
||||
private int totalWeight = 0;
|
||||
|
||||
private ConfigLoader configLoader;
|
||||
|
||||
private Random random;
|
||||
|
||||
|
||||
public ConfigLoader getConfigLoader() {
|
||||
return configLoader;
|
||||
}
|
||||
@@ -66,6 +70,10 @@ public abstract class MultiDataSource extends DataSourceAdapter implements Multi
|
||||
this.configLoader = configLoader;
|
||||
}
|
||||
|
||||
public int getTotalWeight() {
|
||||
return totalWeight;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
if (name == null) {
|
||||
return "HADataSource-" + System.identityHashCode(this);
|
||||
@@ -116,6 +124,8 @@ public abstract class MultiDataSource extends DataSourceAdapter implements Multi
|
||||
return;
|
||||
}
|
||||
|
||||
random = new Random();
|
||||
|
||||
initInternal();
|
||||
|
||||
scheduler = Executors.newScheduledThreadPool(schedulerThreadCount);
|
||||
@@ -190,25 +200,27 @@ public abstract class MultiDataSource extends DataSourceAdapter implements Multi
|
||||
public Map<String, DataSourceHolder> getDataSources() {
|
||||
return dataSources;
|
||||
}
|
||||
|
||||
|
||||
public DataSourceHolder getDataSourceHolder(String name) {
|
||||
return dataSources.get(name);
|
||||
}
|
||||
|
||||
public void addDataSource(String name, DataSourceHolder dataSourceHolder) {
|
||||
dataSources.put(name, dataSourceHolder);
|
||||
|
||||
|
||||
this.totalWeight += dataSourceHolder.getWeight();
|
||||
}
|
||||
|
||||
public Properties getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
||||
public void computeTotalWeight() {
|
||||
int totalWeight = 0;
|
||||
for (DataSourceHolder holder : this.dataSources.values()) {
|
||||
holder.setWeightRegionBegin(totalWeight);
|
||||
totalWeight += holder.getWeight();
|
||||
holder.setWeightReginEnd(totalWeight);
|
||||
}
|
||||
this.totalWeight = totalWeight;
|
||||
}
|
||||
@@ -219,8 +231,27 @@ public abstract class MultiDataSource extends DataSourceAdapter implements Multi
|
||||
return new MultiDataSourceConnection(this, createConnectionId());
|
||||
}
|
||||
|
||||
public abstract MultiConnectionHolder getConnectionInternal(MultiDataSourceConnection conn, String sql)
|
||||
throws SQLException;
|
||||
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;
|
||||
}
|
||||
if (randomNumber >= item.getWeightRegionBegin() && randomNumber < item.getWeightReginEnd()) {
|
||||
dataSource = item;
|
||||
}
|
||||
}
|
||||
if (dataSource == null) {
|
||||
dataSource = first;
|
||||
}
|
||||
|
||||
return dataSource.getConnection();
|
||||
}
|
||||
|
||||
public void handleNotAwailableDatasource(DataSourceHolder dataSourceHolder) {
|
||||
}
|
||||
@@ -228,7 +259,6 @@ public abstract class MultiDataSource extends DataSourceAdapter implements Multi
|
||||
public String[] getDataSourceNames() {
|
||||
return this.dataSources.keySet().toArray(new String[this.dataSources.size()]);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getDbType() {
|
||||
@@ -264,14 +294,14 @@ public abstract class MultiDataSource extends DataSourceAdapter implements Multi
|
||||
public long createTransactionId() {
|
||||
return transactionIdSeed.incrementAndGet();
|
||||
}
|
||||
|
||||
|
||||
public boolean restartDataSource(String name) {
|
||||
DataSourceHolder holder = this.getDataSources().get(name);
|
||||
if (holder != null) {
|
||||
holder.restart();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package com.alibaba.druid.pool.ha.balance;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import com.alibaba.druid.pool.ha.MultiConnectionHolder;
|
||||
import com.alibaba.druid.pool.ha.MultiDataSourceConnection;
|
||||
|
||||
public interface Balancer {
|
||||
|
||||
Connection getConnection(MultiDataSourceConnection connectionProxy, String sql) throws SQLException;
|
||||
MultiConnectionHolder getConnection(MultiDataSourceConnection connectionProxy, String sql) throws SQLException;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.alibaba.druid.pool.ha.balance;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -9,6 +8,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
import com.alibaba.druid.logging.Log;
|
||||
import com.alibaba.druid.logging.LogFactory;
|
||||
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;
|
||||
|
||||
@@ -23,7 +23,7 @@ public class RoundRobinBlancer implements Balancer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection(MultiDataSourceConnection connectionProxy, String sql) throws SQLException {
|
||||
public MultiConnectionHolder getConnection(MultiDataSourceConnection connectionProxy, String sql) throws SQLException {
|
||||
MultiDataSource multiDataSource = connectionProxy.getHaDataSource();
|
||||
|
||||
int tryCount = 0;
|
||||
@@ -59,7 +59,7 @@ public class RoundRobinBlancer implements Balancer {
|
||||
continue;
|
||||
}
|
||||
|
||||
Connection conn = null;
|
||||
MultiConnectionHolder conn = null;
|
||||
|
||||
try {
|
||||
tryCount++;
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
package com.alibaba.druid.pool.ha.balance;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import com.alibaba.druid.pool.ha.MultiDataSource;
|
||||
import com.alibaba.druid.pool.ha.MultiDataSourceConnection;
|
||||
|
||||
public class SimpleBalancer implements Balancer {
|
||||
|
||||
private int maxActive = 8;
|
||||
|
||||
public int getMaxActive() {
|
||||
return maxActive;
|
||||
}
|
||||
|
||||
public void setMaxActive(int maxActive) {
|
||||
this.maxActive = maxActive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection(MultiDataSourceConnection connectionProxy, String sql) throws SQLException {
|
||||
MultiDataSource multiDataSource = connectionProxy.getHaDataSource();
|
||||
|
||||
Object[] array = multiDataSource.getDataSources().values().toArray();
|
||||
|
||||
DruidDataSource minDataSource = null;
|
||||
int min = 0;
|
||||
for (Object item : array) {
|
||||
DruidDataSource dataSource = (DruidDataSource) item;
|
||||
|
||||
if (!dataSource.isEnable()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int activeCount = dataSource.getActiveCount();
|
||||
|
||||
if (minDataSource == null || activeCount < min) {
|
||||
minDataSource = dataSource;
|
||||
min = activeCount;
|
||||
}
|
||||
|
||||
if (activeCount >= maxActive) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return dataSource.getConnection();
|
||||
}
|
||||
|
||||
if (minDataSource != null) {
|
||||
return minDataSource.getConnection();
|
||||
}
|
||||
|
||||
throw new SQLException("can not get connection, no availabe datasources");
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,8 @@ public class CobarDataSource extends MultiDataSource {
|
||||
private List<Filter> proxyFilters = new ArrayList<Filter>();
|
||||
private String filters;
|
||||
|
||||
|
||||
|
||||
public CobarDataSource(){
|
||||
|
||||
}
|
||||
@@ -110,6 +112,7 @@ public class CobarDataSource extends MultiDataSource {
|
||||
|
||||
@Override
|
||||
public MultiConnectionHolder getConnectionInternal(MultiDataSourceConnection conn, String sql) throws SQLException {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
package com.alibaba.druid.pool;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import com.alibaba.druid.pool.ha.config.URLConnectionConfigLoader;
|
||||
|
||||
|
||||
public class URLConfigerLoaderTest extends TestCase {
|
||||
public void test_0 () throws Exception {
|
||||
String url = "http://www.baidu.com/";
|
||||
|
||||
URLConnectionConfigLoader loader = new URLConnectionConfigLoader(url);
|
||||
loader.load();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user