From 04ce5ce7bbb89bef70432ba4ec579406b8f11750 Mon Sep 17 00:00:00 2001 From: wenshao Date: Wed, 21 Dec 2011 15:25:47 +0800 Subject: [PATCH] ha --- .../druid/pool/ha/MultiDataSource.java | 8 +-- .../pool/ha/cobar/CobarConfigLoader.java | 20 +++---- .../druid/pool/ha/cobar/CobarDataSource.java | 18 +++++- .../pool/ha/cobar/CobarFailureDetecter.java | 58 +++++++++++++++++++ .../DefaultDataSourceFailureDetecter.java | 2 +- 5 files changed, 87 insertions(+), 19 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/pool/ha/cobar/CobarFailureDetecter.java 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 f4b45234bf..78ff08932d 100644 --- a/src/main/java/com/alibaba/druid/pool/ha/MultiDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/ha/MultiDataSource.java @@ -47,7 +47,7 @@ public abstract class MultiDataSource extends DataSourceAdapter implements Multi private final AtomicLong busySkipCount = new AtomicLong(); private final AtomicLong retryGetConnectionCount = new AtomicLong(); - protected DataSourceFailureDetecter validDataSourceChecker = new DefaultDataSourceFailureDetecter(); + protected DataSourceFailureDetecter failureDetector = new DefaultDataSourceFailureDetecter(); private long failureDetectPeriodMillis = 3000; private long configLoadPeriodMillis = 1000 * 60; @@ -214,7 +214,7 @@ public abstract class MultiDataSource extends DataSourceAdapter implements Multi public void failureDetect() { int changeCount = 0; for (DataSourceHolder dataSourceHolder : getDataSources().values()) { - boolean isFail = !validDataSourceChecker.isValid(dataSourceHolder.getDataSource()); + boolean isFail = !failureDetector.isValid(dataSourceHolder.getDataSource()); if (isFail != dataSourceHolder.isFail()) { dataSourceHolder.setFail(isFail); @@ -241,11 +241,11 @@ public abstract class MultiDataSource extends DataSourceAdapter implements Multi } public DataSourceFailureDetecter getValidDataSourceChecker() { - return validDataSourceChecker; + return failureDetector; } public void setValidDataSourceChecker(DataSourceFailureDetecter validDataSourceChecker) { - this.validDataSourceChecker = validDataSourceChecker; + this.failureDetector = validDataSourceChecker; } public long createConnectionId() { diff --git a/src/main/java/com/alibaba/druid/pool/ha/cobar/CobarConfigLoader.java b/src/main/java/com/alibaba/druid/pool/ha/cobar/CobarConfigLoader.java index 513d987ce2..2c013cde4b 100644 --- a/src/main/java/com/alibaba/druid/pool/ha/cobar/CobarConfigLoader.java +++ b/src/main/java/com/alibaba/druid/pool/ha/cobar/CobarConfigLoader.java @@ -38,27 +38,23 @@ public class CobarConfigLoader extends URLConnectionConfigLoader implements Conf throw new SQLException("illegal cobar url"); } + // jdbc:cobar://ip:port/sid String rest = jdbcUrl.substring("jdbc:cobar://".length()); String[] items = rest.split("/"); - String loginServerIp = items[0]; - String schemaName = items[1]; + String ip = items[0]; + String sid = items[1]; int port = 80; { - int pos = loginServerIp.indexOf(':'); + int pos = ip.indexOf(':'); if (pos != -1) { - loginServerIp = loginServerIp.substring(0, pos); - port = Integer.parseInt(loginServerIp.substring(pos + 1)); + ip = ip.substring(0, pos); + port = Integer.parseInt(ip.substring(pos + 1)); } } - String url = "http://" + loginServerIp; - - if (port != 80) { - url += ":" + port; - } - - url += "cobarStatusQuery?sid=" + schemaName; + //String url = "http://" + ip + ":" + port + "/cobarStatusQuery?sid=" + sid; + String url = "http://" + ip + ":" + port + "/cobarStatusQuery?sid=" + sid; try { return new URL(url); 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 cf162214b1..b70f81fe32 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 @@ -76,8 +76,22 @@ public class CobarDataSource extends MultiDataSource { if (CobarConfigLoader.isCobar(url)) { this.setConfigLoader(new CobarConfigLoader(this)); - - this.getConfigLoader().load(); + + final int RETRY_COUNT = 3; + for (int i = 0; i < RETRY_COUNT; ++i) { + try { + this.getConfigLoader().load(); + break; + } catch (Exception ex) { + LOG.error("load config error", ex); + + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + return; + } + } + } } else { DataSourceHolder holder = createDataSourceHolder(this.url, 1); this.addDataSource("master", holder); diff --git a/src/main/java/com/alibaba/druid/pool/ha/cobar/CobarFailureDetecter.java b/src/main/java/com/alibaba/druid/pool/ha/cobar/CobarFailureDetecter.java new file mode 100644 index 0000000000..e46508acf5 --- /dev/null +++ b/src/main/java/com/alibaba/druid/pool/ha/cobar/CobarFailureDetecter.java @@ -0,0 +1,58 @@ +package com.alibaba.druid.pool.ha.cobar; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.Statement; + +import com.alibaba.druid.logging.Log; +import com.alibaba.druid.logging.LogFactory; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.pool.ha.valid.DefaultDataSourceFailureDetecter; +import com.alibaba.druid.util.JdbcUtils; + +public class CobarFailureDetecter extends DefaultDataSourceFailureDetecter { + + private final static Log LOG = LogFactory.getLog(CobarFailureDetecter.class); + + private int queryTimeoutSeconds = 30; + + public CobarFailureDetecter(){ + this.setValidateSql("SHOW COBAR_STATUS"); + } + + public int getQueryTimeoutSeconds() { + return queryTimeoutSeconds; + } + + public void setQueryTimeoutSeconds(int queryTimeoutSeconds) { + this.queryTimeoutSeconds = queryTimeoutSeconds; + } + + public boolean isValidConnection(DruidDataSource dataSource, Connection conn) { + Statement stmt = null; + ResultSet rs = null; + try { + stmt = conn.createStatement(); + stmt.setQueryTimeout(queryTimeoutSeconds); + rs = stmt.executeQuery(getValidateSql()); + if (!rs.next()) { + return false; + } + + String status = rs.getString(1); + + if ("on".equalsIgnoreCase(status)) { + return true; + } else { + return false; + } + } catch (Exception ex) { + LOG.error("check datasource valid errror", ex); + return false; + } finally { + JdbcUtils.close(rs); + JdbcUtils.close(stmt); + } + + } +} diff --git a/src/main/java/com/alibaba/druid/pool/ha/valid/DefaultDataSourceFailureDetecter.java b/src/main/java/com/alibaba/druid/pool/ha/valid/DefaultDataSourceFailureDetecter.java index bd30bb5e51..baf6b82d0c 100644 --- a/src/main/java/com/alibaba/druid/pool/ha/valid/DefaultDataSourceFailureDetecter.java +++ b/src/main/java/com/alibaba/druid/pool/ha/valid/DefaultDataSourceFailureDetecter.java @@ -59,7 +59,7 @@ public class DefaultDataSourceFailureDetecter implements DataSourceFailureDetect try { stmt = conn.createStatement(); - stmt.execute(validateSql); + stmt.execute(getValidateSql()); } catch (Exception ex) { LOG.error("check datasource valid errror", ex); } finally {