mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
ha
This commit is contained in:
@@ -40,6 +40,7 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.management.JMException;
|
||||
import javax.management.ObjectName;
|
||||
import javax.management.openmbean.CompositeDataSupport;
|
||||
import javax.security.auth.callback.NameCallback;
|
||||
import javax.security.auth.callback.PasswordCallback;
|
||||
@@ -194,6 +195,7 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
|
||||
|
||||
private boolean dupCloseLogEnable = true;
|
||||
|
||||
private ObjectName objectName;
|
||||
|
||||
public boolean isDupCloseLogEnable() {
|
||||
return dupCloseLogEnable;
|
||||
@@ -202,7 +204,14 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
|
||||
public void setDupCloseLogEnable(boolean dupCloseLogEnable) {
|
||||
this.dupCloseLogEnable = dupCloseLogEnable;
|
||||
}
|
||||
|
||||
|
||||
public ObjectName getObjectName() {
|
||||
return objectName;
|
||||
}
|
||||
|
||||
public void setObjectName(ObjectName objectName) {
|
||||
this.objectName = objectName;
|
||||
}
|
||||
|
||||
public Histogram getTransactionHistogram() {
|
||||
return transactionHistogram;
|
||||
|
||||
@@ -108,8 +108,6 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
|
||||
private String initStackTrace;
|
||||
|
||||
private ObjectName objectName;
|
||||
|
||||
public DruidDataSource(){
|
||||
}
|
||||
|
||||
@@ -117,14 +115,6 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
return initStackTrace;
|
||||
}
|
||||
|
||||
public ObjectName getObjectName() {
|
||||
return objectName;
|
||||
}
|
||||
|
||||
public void setObjectName(ObjectName objectName) {
|
||||
this.objectName = objectName;
|
||||
}
|
||||
|
||||
public boolean isResetStatEnable() {
|
||||
return resetStatEnable;
|
||||
}
|
||||
@@ -703,7 +693,9 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
|
||||
for (;;) {
|
||||
if (poolingCount == 0) {
|
||||
empty.signal(); // send signal to CreateThread create connection
|
||||
if (notEmptyWaitThreadCount == 0) {
|
||||
empty.signal(); // send signal to CreateThread create connection
|
||||
}
|
||||
|
||||
if (estimate <= 0) {
|
||||
throw new GetConnectionTimeoutException();
|
||||
@@ -712,9 +704,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
notEmptyWaitThreadCount++;
|
||||
try {
|
||||
long startEstimate = estimate;
|
||||
estimate = notEmpty.awaitNanos(estimate); // signal by
|
||||
// recycle or
|
||||
// creator
|
||||
estimate = notEmpty.awaitNanos(estimate); // signal by recycle or creator
|
||||
notEmptyWaitCount++;
|
||||
notEmptyWaitNanos += (startEstimate - estimate);
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@ package com.alibaba.druid.pool;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.management.ObjectName;
|
||||
|
||||
/**
|
||||
* @author wenshao<szujobs@hotmail.com>
|
||||
*/
|
||||
@@ -73,4 +75,6 @@ public interface DruidDataSourceMBean extends DruidAbstractDataSourceMBean {
|
||||
Date getPoolingPeakTime();
|
||||
|
||||
long getErrorCount();
|
||||
|
||||
ObjectName getObjectName();
|
||||
}
|
||||
|
||||
@@ -2,9 +2,7 @@ package com.alibaba.druid.pool.ha;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.AbstractList;
|
||||
import java.util.List;
|
||||
import java.util.RandomAccess;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
@@ -13,18 +11,15 @@ import com.alibaba.druid.logging.LogFactory;
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import com.alibaba.druid.pool.ha.balance.Balancer;
|
||||
import com.alibaba.druid.pool.ha.balance.RoundRobinBlancer;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
|
||||
public class HADataSource extends MultiDataSource implements DataSource {
|
||||
|
||||
private final static Log LOG = LogFactory.getLog(HADataSource.class);
|
||||
private final static Log LOG = LogFactory.getLog(HADataSource.class);
|
||||
|
||||
protected DruidDataSource master;
|
||||
protected DruidDataSource slave;
|
||||
protected DruidDataSource master;
|
||||
protected DruidDataSource slave;
|
||||
|
||||
protected Balancer balancer = new RoundRobinBlancer();
|
||||
|
||||
private DataSourceList dataSourceList = new DataSourceList();
|
||||
protected Balancer balancer = new RoundRobinBlancer();
|
||||
|
||||
public HADataSource(){
|
||||
|
||||
@@ -35,6 +30,7 @@ public class HADataSource extends MultiDataSource implements DataSource {
|
||||
}
|
||||
|
||||
public void setMaster(DruidDataSource master) {
|
||||
this.getDataSources().put("master", master);
|
||||
this.master = master;
|
||||
}
|
||||
|
||||
@@ -43,13 +39,10 @@ public class HADataSource extends MultiDataSource implements DataSource {
|
||||
}
|
||||
|
||||
public void setSlave(DruidDataSource slave) {
|
||||
this.getDataSources().put("slave", slave);
|
||||
this.slave = slave;
|
||||
}
|
||||
|
||||
public List<DruidDataSource> getDataSources() {
|
||||
return dataSourceList;
|
||||
}
|
||||
|
||||
public synchronized void setDataSources(List<DruidDataSource> dataSources) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
@@ -77,52 +70,4 @@ public class HADataSource extends MultiDataSource implements DataSource {
|
||||
}
|
||||
}
|
||||
|
||||
private class DataSourceList extends AbstractList<DruidDataSource> implements RandomAccess, java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = -2764017481108945198L;
|
||||
|
||||
public int size() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
public Object[] toArray() {
|
||||
return new DruidDataSource[] { master, slave };
|
||||
}
|
||||
|
||||
public <T> T[] toArray(T[] a) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public DruidDataSource get(int index) {
|
||||
if (index == 0) {
|
||||
return master;
|
||||
}
|
||||
|
||||
if (index == 1) {
|
||||
return slave;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("index : " + index);
|
||||
}
|
||||
|
||||
public DruidDataSource set(int index, DruidDataSource element) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public int indexOf(Object o) {
|
||||
if (o == master) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (o == slave) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public boolean contains(Object o) {
|
||||
return o == master || o == slave;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,10 @@ package com.alibaba.druid.pool.ha;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -32,6 +34,8 @@ public abstract class MultiDataSource extends DataSourceAdapter {
|
||||
|
||||
private boolean inited = false;
|
||||
private final Lock lock = new ReentrantLock();
|
||||
|
||||
private ConcurrentMap<String, DruidDataSource> dataSources = new ConcurrentHashMap<String, DruidDataSource>();
|
||||
|
||||
public MultiDataSource(){
|
||||
|
||||
@@ -94,7 +98,9 @@ public abstract class MultiDataSource extends DataSourceAdapter {
|
||||
return statementIdSeed.incrementAndGet();
|
||||
}
|
||||
|
||||
public abstract List<DruidDataSource> getDataSources();
|
||||
public Map<String, DruidDataSource> getDataSources() {
|
||||
return dataSources;
|
||||
}
|
||||
|
||||
public Properties getProperties() {
|
||||
return properties;
|
||||
@@ -114,7 +120,7 @@ public abstract class MultiDataSource extends DataSourceAdapter {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (DruidDataSource dataSource : getDataSources()) {
|
||||
for (DruidDataSource dataSource : getDataSources().values()) {
|
||||
boolean isValid = validDataSourceChecker.isValid(dataSource);
|
||||
if (isValid) {
|
||||
handleNotAwailableDatasource(dataSource);
|
||||
|
||||
@@ -2,10 +2,48 @@ package com.alibaba.druid.pool.ha.config;
|
||||
|
||||
public class DruidDataSourceConfig {
|
||||
|
||||
private String name;
|
||||
|
||||
private String url;
|
||||
private String user;
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
private int initialSize;
|
||||
protected int maxActive;
|
||||
private int minIdle;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getInitialSize() {
|
||||
return initialSize;
|
||||
}
|
||||
|
||||
public void setInitialSize(int initialSize) {
|
||||
this.initialSize = initialSize;
|
||||
}
|
||||
|
||||
public int getMaxActive() {
|
||||
return maxActive;
|
||||
}
|
||||
|
||||
public void setMaxActive(int maxActive) {
|
||||
this.maxActive = maxActive;
|
||||
}
|
||||
|
||||
public int getMinIdle() {
|
||||
return minIdle;
|
||||
}
|
||||
|
||||
public void setMinIdle(int minIdle) {
|
||||
this.minIdle = minIdle;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
@@ -14,12 +52,12 @@ public class DruidDataSourceConfig {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getUser() {
|
||||
return user;
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUser(String user) {
|
||||
this.user = user;
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
|
||||
@@ -5,8 +5,18 @@ import java.util.List;
|
||||
|
||||
public class MultiDataSourceConfig {
|
||||
|
||||
private String name;
|
||||
|
||||
private List<DruidDataSourceConfig> dataSources = new ArrayList<DruidDataSourceConfig>();
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public List<DruidDataSourceConfig> getDataSources() {
|
||||
return dataSources;
|
||||
}
|
||||
|
||||
@@ -1,17 +1,84 @@
|
||||
package com.alibaba.druid.pool.ha.config;
|
||||
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
public class URLConnectionConfigLoader {
|
||||
import com.alibaba.druid.DruidRuntimeException;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
|
||||
private final URL configServerURL;
|
||||
public class URLConnectionConfigLoader implements ConfigLoader {
|
||||
|
||||
private URL url;
|
||||
private int connectTimeout = 1000 * 3;
|
||||
private int readTimeout;
|
||||
|
||||
public URLConnectionConfigLoader(URL configServerURL){
|
||||
this.configServerURL = configServerURL;
|
||||
this.url = configServerURL;
|
||||
}
|
||||
|
||||
public URL getConfigServerURL() {
|
||||
return configServerURL;
|
||||
public URLConnectionConfigLoader(String url) throws MalformedURLException{
|
||||
this.url = new URL(url);
|
||||
}
|
||||
|
||||
public URL getURL() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setURL(URL url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public int getConnectTimeout() {
|
||||
return connectTimeout;
|
||||
}
|
||||
|
||||
public void setConnectTimeout(int connectTimeout) {
|
||||
this.connectTimeout = connectTimeout;
|
||||
}
|
||||
|
||||
public int getReadTimeout() {
|
||||
return readTimeout;
|
||||
}
|
||||
|
||||
public void setReadTimeout(int readTimeout) {
|
||||
this.readTimeout = readTimeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiDataSourceConfig load() {
|
||||
if (url == null) {
|
||||
throw new IllegalStateException("configServerURL is null");
|
||||
}
|
||||
|
||||
String responseMessage;
|
||||
|
||||
{
|
||||
HttpURLConnection conn = null;
|
||||
Reader reader = null;
|
||||
try {
|
||||
conn = (HttpURLConnection) url.openConnection();
|
||||
|
||||
conn.setConnectTimeout(connectTimeout);
|
||||
conn.setReadTimeout(readTimeout);
|
||||
|
||||
conn.connect();
|
||||
|
||||
reader = new InputStreamReader(conn.getInputStream());
|
||||
responseMessage = JdbcUtils.read(reader);
|
||||
} catch (Exception e) {
|
||||
throw new DruidRuntimeException("load config error, url : " + url.toString());
|
||||
} finally {
|
||||
JdbcUtils.close(reader);
|
||||
conn.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
MultiDataSourceConfig config = JSON.parseObject(responseMessage, MultiDataSourceConfig.class);
|
||||
return config;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user