From 0fd745f4efc4b19b890cb5c6bf154c16bb68eceb Mon Sep 17 00:00:00 2001 From: wenshao Date: Wed, 4 Jul 2012 15:23:59 +0800 Subject: [PATCH] refactor for filter --- .../java/com/alibaba/druid/filter/Filter.java | 6 +- .../alibaba/druid/filter/FilterAdapter.java | 4 +- .../alibaba/druid/filter/FilterChainImpl.java | 4 +- .../alibaba/druid/filter/stat/StatFilter.java | 24 +++++++- .../druid/pool/DruidPooledConnection.java | 10 ++++ .../druid/stat/JdbcDataSourceStat.java | 55 ++++++++++++------- ...DatasourceConnectAndRecycleFilterTest.java | 4 +- .../bvt/proxy/JdbcFilterEventAdapterTest.java | 12 ++-- .../druid/bvt/sql/mysql/CobarHintsTest.java | 19 ++++++- 9 files changed, 97 insertions(+), 41 deletions(-) diff --git a/src/main/java/com/alibaba/druid/filter/Filter.java b/src/main/java/com/alibaba/druid/filter/Filter.java index f1bf13ee79..6a0c2a5ce5 100644 --- a/src/main/java/com/alibaba/druid/filter/Filter.java +++ b/src/main/java/com/alibaba/druid/filter/Filter.java @@ -1277,11 +1277,9 @@ public interface Filter { void clob_truncate(FilterChain chain, ClobProxy wrapper, long len) throws SQLException; - // ///////// - void loadConfig(AbstractDruidFilterConfig druidFilterConfig); - void dataSource_recycle(FilterChain chain, DruidPooledConnection connection) throws SQLException; + void dataSource_releaseConnection(FilterChain chain, DruidPooledConnection connection) throws SQLException; - DruidPooledConnection dataSource_connect(FilterChain chain, DruidDataSource dataSource, long maxWaitMillis) throws SQLException; + DruidPooledConnection dataSource_getConnection(FilterChain chain, DruidDataSource dataSource, long maxWaitMillis) throws SQLException; } diff --git a/src/main/java/com/alibaba/druid/filter/FilterAdapter.java b/src/main/java/com/alibaba/druid/filter/FilterAdapter.java index 86c6c3d5f6..1c44f70302 100644 --- a/src/main/java/com/alibaba/druid/filter/FilterAdapter.java +++ b/src/main/java/com/alibaba/druid/filter/FilterAdapter.java @@ -2704,12 +2704,12 @@ public abstract class FilterAdapter extends NotificationBroadcasterSupport imple // /////////////////// @Override - public void dataSource_recycle(FilterChain chain, DruidPooledConnection connection) throws SQLException { + public void dataSource_releaseConnection(FilterChain chain, DruidPooledConnection connection) throws SQLException { chain.dataSource_recycle(connection); } @Override - public DruidPooledConnection dataSource_connect(FilterChain chain, DruidDataSource dataSource, long maxWaitMillis) throws SQLException { + public DruidPooledConnection dataSource_getConnection(FilterChain chain, DruidDataSource dataSource, long maxWaitMillis) throws SQLException { return chain.dataSource_connect(dataSource, maxWaitMillis); } } diff --git a/src/main/java/com/alibaba/druid/filter/FilterChainImpl.java b/src/main/java/com/alibaba/druid/filter/FilterChainImpl.java index 212741c1c9..0d293e5219 100644 --- a/src/main/java/com/alibaba/druid/filter/FilterChainImpl.java +++ b/src/main/java/com/alibaba/druid/filter/FilterChainImpl.java @@ -4395,7 +4395,7 @@ public class FilterChainImpl implements FilterChain { @Override public void dataSource_recycle(DruidPooledConnection connection) throws SQLException { if (this.pos < filterSize) { - nextFilter().dataSource_recycle(this, connection); + nextFilter().dataSource_releaseConnection(this, connection); return; } @@ -4405,7 +4405,7 @@ public class FilterChainImpl implements FilterChain { @Override public DruidPooledConnection dataSource_connect(DruidDataSource dataSource, long maxWaitMillis) throws SQLException { if (this.pos < filterSize) { - DruidPooledConnection conn = nextFilter().dataSource_connect(this, dataSource, maxWaitMillis); + DruidPooledConnection conn = nextFilter().dataSource_getConnection(this, dataSource, maxWaitMillis); return conn; } diff --git a/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java b/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java index b3d0858cd3..bf73620f69 100644 --- a/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java +++ b/src/main/java/com/alibaba/druid/filter/stat/StatFilter.java @@ -33,6 +33,8 @@ import javax.management.openmbean.TabularData; import com.alibaba.druid.filter.Filter; import com.alibaba.druid.filter.FilterChain; import com.alibaba.druid.filter.FilterEventAdapter; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.pool.DruidPooledConnection; import com.alibaba.druid.proxy.jdbc.CallableStatementProxy; import com.alibaba.druid.proxy.jdbc.ConnectionProxy; import com.alibaba.druid.proxy.jdbc.DataSourceProxy; @@ -706,7 +708,7 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { if (dataSource == null) { return null; } - + return dataSource.getUrl(); } @@ -766,6 +768,26 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean { return dataSourceStat.getConnectionList(); } + public void dataSource_releaseConnection(FilterChain chain, DruidPooledConnection conn) throws SQLException { + chain.dataSource_recycle(conn); + + long nanos = System.nanoTime() - conn.getConnectedTimeNano(); + + long millis = nanos / (1000L * 1000L); + dataSourceStat.getConnectionHoldHistogram().recode(millis); + } + + public DruidPooledConnection dataSource_getConnection(FilterChain chain, DruidDataSource dataSource, + long maxWaitMillis) throws SQLException { + DruidPooledConnection conn = chain.dataSource_connect(dataSource, maxWaitMillis); + + if (conn != null) { + conn.setConnectedTimeNano(System.nanoTime()); + } + + return conn; + } + public static enum Feature { ; diff --git a/src/main/java/com/alibaba/druid/pool/DruidPooledConnection.java b/src/main/java/com/alibaba/druid/pool/DruidPooledConnection.java index 6e786fe102..4532eaab5a 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidPooledConnection.java +++ b/src/main/java/com/alibaba/druid/pool/DruidPooledConnection.java @@ -65,6 +65,8 @@ public class DruidPooledConnection implements javax.sql.PooledConnection, Connec private boolean closed = false; private final Thread ownerThread; + private long connectedTimeNano; + public DruidPooledConnection(ConnectionHolder holder){ this.conn = holder.getConnection(); this.holder = holder; @@ -76,6 +78,14 @@ public class DruidPooledConnection implements javax.sql.PooledConnection, Connec return ownerThread; } + public long getConnectedTimeNano() { + return connectedTimeNano; + } + + public void setConnectedTimeNano(long connectedTimeNano) { + this.connectedTimeNano = connectedTimeNano; + } + public boolean isTraceEnable() { return traceEnable; } diff --git a/src/main/java/com/alibaba/druid/stat/JdbcDataSourceStat.java b/src/main/java/com/alibaba/druid/stat/JdbcDataSourceStat.java index 10b7394bf6..5e1d4367be 100644 --- a/src/main/java/com/alibaba/druid/stat/JdbcDataSourceStat.java +++ b/src/main/java/com/alibaba/druid/stat/JdbcDataSourceStat.java @@ -32,27 +32,35 @@ import javax.management.openmbean.TabularType; import com.alibaba.druid.filter.Filter; import com.alibaba.druid.filter.stat.StatFilter; import com.alibaba.druid.proxy.jdbc.DataSourceProxy; +import com.alibaba.druid.util.Histogram; public class JdbcDataSourceStat implements JdbcDataSourceStatMBean { private final String name; private final String url; - private final JdbcConnectionStat connectionStat = new JdbcConnectionStat(); - private final JdbcResultSetStat resultSetStat = new JdbcResultSetStat(); - private final JdbcStatementStat statementStat = new JdbcStatementStat(); + private final JdbcConnectionStat connectionStat = new JdbcConnectionStat(); + private final JdbcResultSetStat resultSetStat = new JdbcResultSetStat(); + private final JdbcStatementStat statementStat = new JdbcStatementStat(); - private int maxSize = 1000 * 1; + private int maxSize = 1000 * 1; - private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); - private final LinkedHashMap sqlStatMap = new LinkedHashMap( - maxSize, - 0.75f, - false); + private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + private final LinkedHashMap sqlStatMap = new LinkedHashMap( + maxSize, + 0.75f, + false); + + private final Histogram connectionHoldHistogram = new Histogram(new long[] { // + // + 1, 10, 100, 1000, 10 * 1000, // + 100 * 1000, 1000 * 1000 + // + }); // private final ConcurrentMap sqlStatMap = new ConcurrentHashMap(); - private final ConcurrentMap connections = new ConcurrentHashMap(); + private final ConcurrentMap connections = new ConcurrentHashMap(); public JdbcDataSourceStat(String name, String url){ this.name = name; @@ -63,19 +71,20 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean { connectionStat.reset(); statementStat.reset(); resultSetStat.reset(); - + connectionHoldHistogram.reset(); + lock.writeLock().lock(); try { - Iterator> iter = sqlStatMap.entrySet().iterator(); - while (iter.hasNext()) { - Map.Entry entry = iter.next(); - JdbcSqlStat stat = entry.getValue(); - if (stat.getExecuteCount() == 0) { - iter.remove(); - } else { - stat.reset(); - } - } + Iterator> iter = sqlStatMap.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = iter.next(); + JdbcSqlStat stat = entry.getValue(); + if (stat.getExecuteCount() == 0) { + iter.remove(); + } else { + stat.reset(); + } + } } finally { lock.writeLock().unlock(); } @@ -86,6 +95,10 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean { // connections.clear(); } + public Histogram getConnectionHoldHistogram() { + return connectionHoldHistogram; + } + public JdbcConnectionStat getConnectionStat() { return connectionStat; } diff --git a/src/test/java/com/alibaba/druid/bvt/filter/FilterDatasourceConnectAndRecycleFilterTest.java b/src/test/java/com/alibaba/druid/bvt/filter/FilterDatasourceConnectAndRecycleFilterTest.java index 2df39e05f2..17a11ac710 100644 --- a/src/test/java/com/alibaba/druid/bvt/filter/FilterDatasourceConnectAndRecycleFilterTest.java +++ b/src/test/java/com/alibaba/druid/bvt/filter/FilterDatasourceConnectAndRecycleFilterTest.java @@ -49,13 +49,13 @@ public class FilterDatasourceConnectAndRecycleFilterTest extends TestCase { private AtomicLong dataSourceRecycleCount = new AtomicLong(); @Override - public void dataSource_recycle(FilterChain chain, DruidPooledConnection connection) throws SQLException { + public void dataSource_releaseConnection(FilterChain chain, DruidPooledConnection connection) throws SQLException { chain.dataSource_recycle(connection); dataSourceRecycleCount.incrementAndGet(); } @Override - public DruidPooledConnection dataSource_connect(FilterChain chain, DruidDataSource dataSource, + public DruidPooledConnection dataSource_getConnection(FilterChain chain, DruidDataSource dataSource, long maxWaitMillis) throws SQLException { dataSourceConnectCount.incrementAndGet(); return chain.dataSource_connect(dataSource, maxWaitMillis); diff --git a/src/test/java/com/alibaba/druid/bvt/proxy/JdbcFilterEventAdapterTest.java b/src/test/java/com/alibaba/druid/bvt/proxy/JdbcFilterEventAdapterTest.java index 77b779b9a8..c57cad1dc3 100644 --- a/src/test/java/com/alibaba/druid/bvt/proxy/JdbcFilterEventAdapterTest.java +++ b/src/test/java/com/alibaba/druid/bvt/proxy/JdbcFilterEventAdapterTest.java @@ -799,7 +799,7 @@ public class JdbcFilterEventAdapterTest extends TestCase { Throwable error = null; try { - filter.dataSource_recycle(chain, null); + filter.dataSource_releaseConnection(chain, null); } catch (SQLException ex) { error = ex; } @@ -816,7 +816,7 @@ public class JdbcFilterEventAdapterTest extends TestCase { Throwable error = null; try { - filter.dataSource_recycle(chain, null); + filter.dataSource_releaseConnection(chain, null); } catch (RuntimeException ex) { error = ex; } @@ -833,7 +833,7 @@ public class JdbcFilterEventAdapterTest extends TestCase { Throwable error = null; try { - filter.dataSource_recycle(chain, null); + filter.dataSource_releaseConnection(chain, null); } catch (Error ex) { error = ex; } @@ -853,7 +853,7 @@ public class JdbcFilterEventAdapterTest extends TestCase { Throwable error = null; try { - filter.dataSource_connect(chain, null, 0L); + filter.dataSource_getConnection(chain, null, 0L); } catch (SQLException ex) { error = ex; } @@ -871,7 +871,7 @@ public class JdbcFilterEventAdapterTest extends TestCase { Throwable error = null; try { - filter.dataSource_connect(chain, null, 0L); + filter.dataSource_getConnection(chain, null, 0L); } catch (RuntimeException ex) { error = ex; } @@ -889,7 +889,7 @@ public class JdbcFilterEventAdapterTest extends TestCase { Throwable error = null; try { - filter.dataSource_connect(chain, null, 0L); + filter.dataSource_getConnection(chain, null, 0L); } catch (Error ex) { error = ex; } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/CobarHintsTest.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/CobarHintsTest.java index 0ecbc0829f..3105692f4b 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/mysql/CobarHintsTest.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/CobarHintsTest.java @@ -3,11 +3,24 @@ package com.alibaba.druid.bvt.sql.mysql; import junit.framework.TestCase; import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils; +import com.alibaba.druid.util.JdbcUtils; public class CobarHintsTest extends TestCase { public void test_0 () throws Exception { - String sql = "/*!cobar: select,4,ireport.dm_mdm_mem_prod_noeff_sdt0.admin_member_seq=45654723*/ select * from t"; - - SQLUtils.formatMySql(sql); + String sql = "/*!cobar: select,4,ireport.dm_mdm_mem_prod_noeff_sdt0.admin_member_seq=45654723*/ " + + "select product_id, noeff_days,total_cnt from (" + + "select product_id," + + " noeff_days," + + " count(*) over() as total_cnt " + + " from ( " + + " select product_id," + + " noeff_days " + + " from ireport.dm_mdm_mem_prod_noeff_sdt0" + + " where admin_member_seq = 45654723" + + ") b Order by product_id desc ) a limit 25 offset (1-1)*20"; + + String mergedSql = ParameterizedOutputVisitorUtils.parameterize(sql, JdbcUtils.POSTGRESQL); + System.out.println(mergedSql); } }