From 0d78a27d48a701b705efa9e9b0c6c802c4639eee Mon Sep 17 00:00:00 2001 From: DigitalSonic Date: Thu, 12 Jul 2018 00:00:24 +0800 Subject: [PATCH] Fix validation bug fix the following situation: 1. rawURL can not meet the need to create Connection 2. username and password are not given in Properties if testOnBorrow or testOnReturn is set to true, the ValidationThread will be disabled. --- .../druid/pool/ha/DataSourceCreator.java | 4 ++-- .../ha/selector/RandomDataSourceSelector.java | 16 +++++++++---- .../RandomDataSourceValidateThread.java | 24 +++++++++++-------- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/alibaba/druid/pool/ha/DataSourceCreator.java b/src/main/java/com/alibaba/druid/pool/ha/DataSourceCreator.java index d5fc9dd5b7..5d2d4906a4 100644 --- a/src/main/java/com/alibaba/druid/pool/ha/DataSourceCreator.java +++ b/src/main/java/com/alibaba/druid/pool/ha/DataSourceCreator.java @@ -122,8 +122,8 @@ public class DataSourceCreator { private void loadNameList() { Set names = new HashSet(); for (String n : properties.stringPropertyNames()) { - if (n.contains(".")) { - names.add(n.split("\\.")[0]); + if (n.contains(".url")) { + names.add(n.split("\\.url")[0]); } } if (!names.isEmpty()) { diff --git a/src/main/java/com/alibaba/druid/pool/ha/selector/RandomDataSourceSelector.java b/src/main/java/com/alibaba/druid/pool/ha/selector/RandomDataSourceSelector.java index 345bff84bc..b9f0d5c717 100644 --- a/src/main/java/com/alibaba/druid/pool/ha/selector/RandomDataSourceSelector.java +++ b/src/main/java/com/alibaba/druid/pool/ha/selector/RandomDataSourceSelector.java @@ -17,6 +17,8 @@ package com.alibaba.druid.pool.ha.selector; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.pool.ha.HighAvailableDataSource; +import com.alibaba.druid.support.logging.Log; +import com.alibaba.druid.support.logging.LogFactory; import javax.sql.DataSource; import java.util.Collection; @@ -33,6 +35,8 @@ import java.util.concurrent.CopyOnWriteArrayList; * @author DigitalSonic */ public class RandomDataSourceSelector implements DataSourceSelector { + private final static Log LOG = LogFactory.getLog(RandomDataSourceSelector.class); + private Random random = new Random(); private List blacklist = new CopyOnWriteArrayList(); private HighAvailableDataSource highAvailableDataSource; @@ -41,10 +45,14 @@ public class RandomDataSourceSelector implements DataSourceSelector { public RandomDataSourceSelector(HighAvailableDataSource highAvailableDataSource) { this.highAvailableDataSource = highAvailableDataSource; - validateThread = new RandomDataSourceValidateThread(this); - recoverThread = new RandomDataSourceRecoverThread(this); - new Thread(validateThread, "RandomDataSourceSelector-validate-thread").start(); - new Thread(recoverThread, "RandomDataSourceSelector-recover-thread").start(); + if (!highAvailableDataSource.isTestOnBorrow() && !highAvailableDataSource.isTestOnReturn()) { + validateThread = new RandomDataSourceValidateThread(this); + recoverThread = new RandomDataSourceRecoverThread(this); + new Thread(validateThread, "RandomDataSourceSelector-validate-thread").start(); + new Thread(recoverThread, "RandomDataSourceSelector-recover-thread").start(); + } else { + LOG.info("testOnBorrow or testOnReturn has been set to true, ignore validateThread"); + } } @Override diff --git a/src/main/java/com/alibaba/druid/pool/ha/selector/RandomDataSourceValidateThread.java b/src/main/java/com/alibaba/druid/pool/ha/selector/RandomDataSourceValidateThread.java index a1900a8634..e2887fe349 100644 --- a/src/main/java/com/alibaba/druid/pool/ha/selector/RandomDataSourceValidateThread.java +++ b/src/main/java/com/alibaba/druid/pool/ha/selector/RandomDataSourceValidateThread.java @@ -18,6 +18,7 @@ package com.alibaba.druid.pool.ha.selector; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.support.logging.Log; import com.alibaba.druid.support.logging.LogFactory; +import com.alibaba.druid.util.JdbcUtils; import javax.sql.DataSource; import java.sql.Connection; @@ -95,25 +96,28 @@ public class RandomDataSourceValidateThread implements Runnable { private boolean check(String name, DruidDataSource dataSource) { boolean result = true; Driver driver = dataSource.getRawDriver(); - Properties info = dataSource.getConnectProperties(); - String url = dataSource.getRawJdbcUrl(); + Properties info = new Properties(dataSource.getConnectProperties()); + String username = dataSource.getUsername(); + String password = dataSource.getPassword(); + String url = dataSource.getUrl(); // We can't use rawUrl here, because the schema maybe set in url. Connection conn = null; + if (info.getProperty("user") == null && username != null) { + info.setProperty("user", username); + } + if (info.getProperty("password") == null && password != null) { + info.setProperty("password", password); + } try { LOG.debug("Validating " + name + " every " + sleepSeconds + " seconds."); conn = driver.connect(url, info); dataSource.validateConnection(conn); } catch (SQLException e) { - LOG.warn("Validation FAILED for " + name + ". Exception: " + e.getMessage()); + LOG.warn("Validation FAILED for " + name + " with url [" + url + "] and username [" + + info.getProperty("user") + "]. Exception: " + e.getMessage()); result = false; } finally { - if (conn != null) { - try { - conn.close(); - } catch (SQLException e) { - LOG.error("Can not close connection for HostAndPort Validation.", e); - } - } + JdbcUtils.close(conn); } return result;