diff --git a/src/main/java/com/alibaba/druid/pool/ha/DataSourceHolder.java b/src/main/java/com/alibaba/druid/pool/ha/DataSourceHolder.java index 159a2835eb..ae8da73898 100644 --- a/src/main/java/com/alibaba/druid/pool/ha/DataSourceHolder.java +++ b/src/main/java/com/alibaba/druid/pool/ha/DataSourceHolder.java @@ -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; diff --git a/src/main/java/com/alibaba/druid/pool/ha/HADataSource.java b/src/main/java/com/alibaba/druid/pool/ha/HADataSource.java index 75da0110e2..14ccd7b20b 100644 --- a/src/main/java/com/alibaba/druid/pool/ha/HADataSource.java +++ b/src/main/java/com/alibaba/druid/pool/ha/HADataSource.java @@ -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() { diff --git a/src/main/java/com/alibaba/druid/pool/ha/MultiDataSource.java b/src/main/java/com/alibaba/druid/pool/ha/MultiDataSource.java index 438f7783ce..fce1b69ae9 100644 --- a/src/main/java/com/alibaba/druid/pool/ha/MultiDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/ha/MultiDataSource.java @@ -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 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; } diff --git a/src/main/java/com/alibaba/druid/pool/ha/balance/Balancer.java b/src/main/java/com/alibaba/druid/pool/ha/balance/Balancer.java index 7d82112536..573942cc74 100644 --- a/src/main/java/com/alibaba/druid/pool/ha/balance/Balancer.java +++ b/src/main/java/com/alibaba/druid/pool/ha/balance/Balancer.java @@ -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; } diff --git a/src/main/java/com/alibaba/druid/pool/ha/balance/RoundRobinBlancer.java b/src/main/java/com/alibaba/druid/pool/ha/balance/RoundRobinBlancer.java index d335c71278..8bd70e262c 100644 --- a/src/main/java/com/alibaba/druid/pool/ha/balance/RoundRobinBlancer.java +++ b/src/main/java/com/alibaba/druid/pool/ha/balance/RoundRobinBlancer.java @@ -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++; diff --git a/src/main/java/com/alibaba/druid/pool/ha/balance/SimpleBalancer.java b/src/main/java/com/alibaba/druid/pool/ha/balance/SimpleBalancer.java deleted file mode 100644 index a378888552..0000000000 --- a/src/main/java/com/alibaba/druid/pool/ha/balance/SimpleBalancer.java +++ /dev/null @@ -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"); - } -} diff --git a/src/main/java/com/alibaba/druid/pool/ha/cobar/CobarDataSource.java b/src/main/java/com/alibaba/druid/pool/ha/cobar/CobarDataSource.java index 7a296df1c0..8780dee8de 100644 --- a/src/main/java/com/alibaba/druid/pool/ha/cobar/CobarDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/ha/cobar/CobarDataSource.java @@ -27,6 +27,8 @@ public class CobarDataSource extends MultiDataSource { private List proxyFilters = new ArrayList(); 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; } diff --git a/src/test/java/com/alibaba/druid/pool/URLConfigerLoaderTest.java b/src/test/java/com/alibaba/druid/pool/URLConfigerLoaderTest.java deleted file mode 100644 index c67cf03aa0..0000000000 --- a/src/test/java/com/alibaba/druid/pool/URLConfigerLoaderTest.java +++ /dev/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(); - } -}