diff --git a/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java b/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java index 7ee70e68ba..09add0fd33 100644 --- a/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java +++ b/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java @@ -18,6 +18,7 @@ package com.alibaba.druid.stat; import java.util.Date; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; import java.util.concurrent.atomic.AtomicLongFieldUpdater; import javax.management.JMException; @@ -29,7 +30,6 @@ import javax.management.openmbean.SimpleType; import com.alibaba.druid.proxy.DruidDriver; import com.alibaba.druid.proxy.jdbc.StatementExecuteType; -import com.alibaba.druid.util.Histogram; import com.alibaba.druid.util.IOUtils; import com.alibaba.druid.util.JMXUtils; @@ -38,129 +38,189 @@ import com.alibaba.druid.util.JMXUtils; */ public final class JdbcSqlStat implements JdbcSqlStatMBean { - private final String sql; - private long id; - private String dataSource; - private long executeLastStartTime; + private final String sql; + private long id; + private String dataSource; + private long executeLastStartTime; - private volatile long executeBatchSizeTotal; - private volatile long executeBatchSizeMax; + private volatile long executeBatchSizeTotal; + private volatile int executeBatchSizeMax; - private volatile long executeSuccessCount; - private volatile long executeSpanNanoTotal; - private volatile long executeSpanNanoMax; - private volatile long runningCount; - private volatile long concurrentMax; - private volatile long resultSetHoldTimeNano; - private volatile long executeAndResultSetHoldTime; + private volatile long executeSuccessCount; + private volatile long executeSpanNanoTotal; + private volatile long executeSpanNanoMax; + private volatile int runningCount; + private volatile int concurrentMax; + private volatile long resultSetHoldTimeNano; + private volatile long executeAndResultSetHoldTime; - final static AtomicLongFieldUpdater executeBatchSizeTotalUpdater; - final static AtomicLongFieldUpdater executeBatchSizeMaxUpdater; - - final static AtomicLongFieldUpdater executeSuccessCountUpdater; - final static AtomicLongFieldUpdater executeSpanNanoTotalUpdater; - final static AtomicLongFieldUpdater executeSpanNanoMaxUpdater; - final static AtomicLongFieldUpdater runningCountUpdater; - final static AtomicLongFieldUpdater concurrentMaxUpdater; - final static AtomicLongFieldUpdater resultSetHoldTimeNanoUpdater; - final static AtomicLongFieldUpdater executeAndResultSetHoldTimeUpdater; - static { - executeBatchSizeTotalUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, "executeBatchSizeTotal"); - executeBatchSizeMaxUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, "executeBatchSizeMax"); - - executeSuccessCountUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, "executeSuccessCount"); - executeSpanNanoTotalUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, "executeSpanNanoTotal"); - executeSpanNanoMaxUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, "executeSpanNanoMax"); - runningCountUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, "runningCount"); - concurrentMaxUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, "concurrentMax"); - resultSetHoldTimeNanoUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, "resultSetHoldTimeNano"); - executeAndResultSetHoldTimeUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, - "executeAndResultSetHoldTime"); - } + final static AtomicLongFieldUpdater executeBatchSizeTotalUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "executeBatchSizeTotal"); + final static AtomicIntegerFieldUpdater executeBatchSizeMaxUpdater = AtomicIntegerFieldUpdater.newUpdater(JdbcSqlStat.class, + "executeBatchSizeMax"); - private String name; - private String file; - private String dbType; + final static AtomicLongFieldUpdater executeSuccessCountUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "executeSuccessCount"); + final static AtomicLongFieldUpdater executeSpanNanoTotalUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "executeSpanNanoTotal"); + final static AtomicLongFieldUpdater executeSpanNanoMaxUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "executeSpanNanoMax"); + final static AtomicIntegerFieldUpdater runningCountUpdater = AtomicIntegerFieldUpdater.newUpdater(JdbcSqlStat.class, + "runningCount"); + final static AtomicIntegerFieldUpdater concurrentMaxUpdater = AtomicIntegerFieldUpdater.newUpdater(JdbcSqlStat.class, + "concurrentMax"); + final static AtomicLongFieldUpdater resultSetHoldTimeNanoUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "resultSetHoldTimeNano"); + final static AtomicLongFieldUpdater executeAndResultSetHoldTimeUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "executeAndResultSetHoldTime"); - private long executeNanoSpanMaxOccurTime; + private String name; + private String file; + private String dbType; - private volatile long executeErrorCount; - private Throwable executeErrorLast; - private long executeErrorLastTime; + private volatile long executeNanoSpanMaxOccurTime; - private volatile long updateCount; - private volatile long updateCountMax; - private volatile long fetchRowCount; - private volatile long fetchRowCountMax; + private volatile long executeErrorCount; + private volatile Throwable executeErrorLast; + private volatile long executeErrorLastTime; - private volatile long inTransactionCount; + private volatile long updateCount; + private volatile long updateCountMax; + private volatile long fetchRowCount; + private volatile long fetchRowCountMax; - private String lastSlowParameters; + private volatile long inTransactionCount; - private boolean removed = false; + private volatile String lastSlowParameters; - private volatile long clobOpenCount; - private volatile long blobOpenCount; - private volatile long readStringLength; - private volatile long readBytesLength; + private boolean removed = false; - private volatile long inputStreamOpenCount; - private volatile long readerOpenCount; + private volatile long clobOpenCount; + private volatile long blobOpenCount; + private volatile long readStringLength; + private volatile long readBytesLength; - final static AtomicLongFieldUpdater executeErrorCountUpdater; - final static AtomicLongFieldUpdater updateCountUpdater; - final static AtomicLongFieldUpdater updateCountMaxUpdater; - final static AtomicLongFieldUpdater fetchRowCountUpdater; - final static AtomicLongFieldUpdater fetchRowCountMaxUpdater; - final static AtomicLongFieldUpdater inTransactionCountUpdater; + private volatile long inputStreamOpenCount; + private volatile long readerOpenCount; - final static AtomicLongFieldUpdater clobOpenCountUpdater; - final static AtomicLongFieldUpdater blobOpenCountUpdater; - final static AtomicLongFieldUpdater readStringLengthUpdater; - final static AtomicLongFieldUpdater readBytesLengthUpdater; + final static AtomicLongFieldUpdater executeErrorCountUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "executeErrorCount"); + final static AtomicLongFieldUpdater updateCountUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "updateCount"); + final static AtomicLongFieldUpdater updateCountMaxUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "updateCountMax"); + final static AtomicLongFieldUpdater fetchRowCountUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "fetchRowCount"); + final static AtomicLongFieldUpdater fetchRowCountMaxUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "fetchRowCountMax"); + final static AtomicLongFieldUpdater inTransactionCountUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "inTransactionCount"); - final static AtomicLongFieldUpdater inputStreamOpenCountUpdater; - final static AtomicLongFieldUpdater readerOpenCountUpdater; + final static AtomicLongFieldUpdater clobOpenCountUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "clobOpenCount"); + final static AtomicLongFieldUpdater blobOpenCountUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "blobOpenCount"); + final static AtomicLongFieldUpdater readStringLengthUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "readStringLength"); + final static AtomicLongFieldUpdater readBytesLengthUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "readBytesLength"); - static { - executeErrorCountUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, "executeErrorCount"); + final static AtomicLongFieldUpdater inputStreamOpenCountUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "inputStreamOpenCount"); + final static AtomicLongFieldUpdater readerOpenCountUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "readerOpenCount"); - updateCountUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, "updateCount"); - updateCountMaxUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, "updateCountMax"); - fetchRowCountUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, "fetchRowCount"); - fetchRowCountMaxUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, "fetchRowCountMax"); - inTransactionCountUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, "inTransactionCount"); + private volatile long histogram_0_1; + private volatile long histogram_1_10; + private volatile int histogram_10_100; + private volatile int histogram_100_1000; + private volatile int histogram_1000_10000; + private volatile int histogram_10000_100000; + private volatile int histogram_100000_1000000; + private volatile int histogram_1000000_more; - clobOpenCountUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, "clobOpenCount"); - blobOpenCountUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, "blobOpenCount"); - readStringLengthUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, "readStringLength"); - readBytesLengthUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, "readBytesLength"); + final static AtomicLongFieldUpdater histogram_0_1_Updater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "histogram_0_1"); + final static AtomicLongFieldUpdater histogram_1_10_Updater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "histogram_1_10"); + final static AtomicIntegerFieldUpdater histogram_10_100_Updater = AtomicIntegerFieldUpdater.newUpdater(JdbcSqlStat.class, + "histogram_10_100"); + final static AtomicIntegerFieldUpdater histogram_100_1000_Updater = AtomicIntegerFieldUpdater.newUpdater(JdbcSqlStat.class, + "histogram_100_1000"); + final static AtomicIntegerFieldUpdater histogram_1000_10000_Updater = AtomicIntegerFieldUpdater.newUpdater(JdbcSqlStat.class, + "histogram_1000_10000"); + final static AtomicIntegerFieldUpdater histogram_10000_100000_Updater = AtomicIntegerFieldUpdater.newUpdater(JdbcSqlStat.class, + "histogram_10000_100000"); + final static AtomicIntegerFieldUpdater histogram_100000_1000000_Updater = AtomicIntegerFieldUpdater.newUpdater(JdbcSqlStat.class, + "histogram_100000_1000000"); + final static AtomicIntegerFieldUpdater histogram_1000000_more_Updater = AtomicIntegerFieldUpdater.newUpdater(JdbcSqlStat.class, + "histogram_1000000_more"); - inputStreamOpenCountUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, "inputStreamOpenCount"); - readerOpenCountUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, "readerOpenCount"); - } + private volatile long executeAndResultHoldTime_0_1; + private volatile long executeAndResultHoldTime_1_10; + private volatile int executeAndResultHoldTime_10_100; + private volatile int executeAndResultHoldTime_100_1000; + private volatile int executeAndResultHoldTime_1000_10000; + private volatile int executeAndResultHoldTime_10000_100000; + private volatile int executeAndResultHoldTime_100000_1000000; + private volatile int executeAndResultHoldTime_1000000_more; - private final Histogram histogram = new Histogram(new long[] { // - // - 1, 10, 100, 1000, 10 * 1000, // - 100 * 1000, 1000 * 1000 - // - }); + final static AtomicLongFieldUpdater executeAndResultHoldTime_0_1_Updater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "executeAndResultHoldTime_0_1"); + final static AtomicLongFieldUpdater executeAndResultHoldTime_1_10_Updater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "executeAndResultHoldTime_1_10"); + final static AtomicIntegerFieldUpdater executeAndResultHoldTime_10_100_Updater = AtomicIntegerFieldUpdater.newUpdater(JdbcSqlStat.class, + "executeAndResultHoldTime_10_100"); + final static AtomicIntegerFieldUpdater executeAndResultHoldTime_100_1000_Updater = AtomicIntegerFieldUpdater.newUpdater(JdbcSqlStat.class, + "executeAndResultHoldTime_100_1000"); + final static AtomicIntegerFieldUpdater executeAndResultHoldTime_1000_10000_Updater = AtomicIntegerFieldUpdater.newUpdater(JdbcSqlStat.class, + "executeAndResultHoldTime_1000_10000"); + final static AtomicIntegerFieldUpdater executeAndResultHoldTime_10000_100000_Updater = AtomicIntegerFieldUpdater.newUpdater(JdbcSqlStat.class, + "executeAndResultHoldTime_10000_100000"); + final static AtomicIntegerFieldUpdater executeAndResultHoldTime_100000_1000000_Updater = AtomicIntegerFieldUpdater.newUpdater(JdbcSqlStat.class, + "executeAndResultHoldTime_100000_1000000"); + final static AtomicIntegerFieldUpdater executeAndResultHoldTime_1000000_more_Updater = AtomicIntegerFieldUpdater.newUpdater(JdbcSqlStat.class, + "executeAndResultHoldTime_1000000_more"); - private final Histogram executeAndResultHoldTimeHistogram = new Histogram(new long[] { // - // - 1, 10, 100, 1000, 10 * 1000, // - 100 * 1000, 1000 * 1000 - // - }); + private volatile long fetchRowCount_0_1; + private volatile long fetchRowCount_1_10; + private volatile long fetchRowCount_10_100; + private volatile int fetchRowCount_100_1000; + private volatile int fetchRowCount_1000_10000; + private volatile int fetchRowCount_10000_more; - private final Histogram fetchRowCountHistogram = new Histogram(new long[] { // - 1, 10, 100, - 1000, 10 * 1000 }); + final static AtomicLongFieldUpdater fetchRowCount_0_1_Updater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "fetchRowCount_0_1"); + final static AtomicLongFieldUpdater fetchRowCount_1_10_Updater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "fetchRowCount_1_10"); + final static AtomicLongFieldUpdater fetchRowCount_10_100_Updater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "fetchRowCount_10_100"); + final static AtomicIntegerFieldUpdater fetchRowCount_100_1000_Updater = AtomicIntegerFieldUpdater.newUpdater(JdbcSqlStat.class, + "fetchRowCount_100_1000"); + final static AtomicIntegerFieldUpdater fetchRowCount_1000_10000_Updater = AtomicIntegerFieldUpdater.newUpdater(JdbcSqlStat.class, + "fetchRowCount_1000_10000"); + final static AtomicIntegerFieldUpdater fetchRowCount_10000_more_Updater = AtomicIntegerFieldUpdater.newUpdater(JdbcSqlStat.class, + "fetchRowCount_10000_more"); - private final Histogram updateCountHistogram = new Histogram(new long[] { // - 1, 10, 100, - 1000, 10 * 1000 }); + private volatile long updateCount_0_1; + private volatile long updateCount_1_10; + private volatile long updateCount_10_100; + private volatile int updateCount_100_1000; + private volatile int updateCount_1000_10000; + private volatile int updateCount_10000_more; + + final static AtomicLongFieldUpdater updateCount_0_1_Updater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "updateCount_0_1"); + final static AtomicLongFieldUpdater updateCount_1_10_Updater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "updateCount_1_10"); + final static AtomicLongFieldUpdater updateCount_10_100_Updater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, + "updateCount_10_100"); + final static AtomicIntegerFieldUpdater updateCount_100_1000_Updater = AtomicIntegerFieldUpdater.newUpdater(JdbcSqlStat.class, + "updateCount_100_1000"); + final static AtomicIntegerFieldUpdater updateCount_1000_10000_Updater = AtomicIntegerFieldUpdater.newUpdater(JdbcSqlStat.class, + "updateCount_1000_10000"); + final static AtomicIntegerFieldUpdater updateCount_10000_more_Updater = AtomicIntegerFieldUpdater.newUpdater(JdbcSqlStat.class, + "updateCount_10000_more"); public JdbcSqlStat(String sql){ this.sql = sql; @@ -279,14 +339,42 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { fetchRowCountUpdater.set(this, 0); fetchRowCountMaxUpdater.set(this, 0); - histogram.reset(); + histogram_0_1_Updater.set(this, 0); + histogram_1_10_Updater.set(this, 0); + histogram_10_100_Updater.set(this, 0); + histogram_100_1000_Updater.set(this, 0); + histogram_1000_10000_Updater.set(this, 0); + histogram_10000_100000_Updater.set(this, 0); + histogram_100000_1000000_Updater.set(this, 0); + histogram_1000000_more_Updater.set(this, 0); + this.lastSlowParameters = null; inTransactionCountUpdater.set(this, 0); resultSetHoldTimeNanoUpdater.set(this, 0); executeAndResultSetHoldTimeUpdater.set(this, 0); - fetchRowCountHistogram.reset(); - updateCountHistogram.reset(); - executeAndResultHoldTimeHistogram.reset(); + + fetchRowCount_0_1_Updater.set(this, 0); + fetchRowCount_1_10_Updater.set(this, 0); + fetchRowCount_10_100_Updater.set(this, 0); + fetchRowCount_100_1000_Updater.set(this, 0); + fetchRowCount_1000_10000_Updater.set(this, 0); + fetchRowCount_10000_more_Updater.set(this, 0); + + updateCount_0_1_Updater.set(this, 0); + updateCount_1_10_Updater.set(this, 0); + updateCount_10_100_Updater.set(this, 0); + updateCount_100_1000_Updater.set(this, 0); + updateCount_1000_10000_Updater.set(this, 0); + updateCount_10000_more_Updater.set(this, 0); + + executeAndResultHoldTime_0_1_Updater.set(this, 0); + executeAndResultHoldTime_1_10_Updater.set(this, 0); + executeAndResultHoldTime_10_100_Updater.set(this, 0); + executeAndResultHoldTime_100_1000_Updater.set(this, 0); + executeAndResultHoldTime_1000_10000_Updater.set(this, 0); + executeAndResultHoldTime_10000_100000_Updater.set(this, 0); + executeAndResultHoldTime_100000_1000000_Updater.set(this, 0); + executeAndResultHoldTime_1000000_more_Updater.set(this, 0); blobOpenCountUpdater.set(this, 0); clobOpenCountUpdater.set(this, 0); @@ -318,7 +406,19 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { } } - this.updateCountHistogram.record(delta); + if (delta < 1) { + updateCount_0_1_Updater.incrementAndGet(this); + } else if (delta < 10) { + updateCount_1_10_Updater.incrementAndGet(this); + } else if (delta < 100) { + updateCount_10_100_Updater.incrementAndGet(this); + } else if (delta < 1000) { + updateCount_100_1000_Updater.incrementAndGet(this); + } else if (delta < 10000) { + updateCount_1000_10000_Updater.incrementAndGet(this); + } else { + updateCount_10000_more_Updater.incrementAndGet(this); + } } public long getUpdateCount() { @@ -434,7 +534,20 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { break; } } - this.fetchRowCountHistogram.record(delta); + + if (delta < 1) { + fetchRowCount_0_1_Updater.incrementAndGet(this); + } else if (delta < 10) { + fetchRowCount_1_10_Updater.incrementAndGet(this); + } else if (delta < 100) { + fetchRowCount_10_100_Updater.incrementAndGet(this); + } else if (delta < 1000) { + fetchRowCount_100_1000_Updater.incrementAndGet(this); + } else if (delta < 10000) { + fetchRowCount_1000_10000_Updater.incrementAndGet(this); + } else { + fetchRowCount_10000_more_Updater.incrementAndGet(this); + } } @@ -443,9 +556,9 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { // executeBatchSizeMax for (;;) { - long current = executeBatchSizeMaxUpdater.get(this); + int current = executeBatchSizeMaxUpdater.get(this); if (current < batchSize) { - if (executeBatchSizeMaxUpdater.compareAndSet(this, current, batchSize)) { + if (executeBatchSizeMaxUpdater.compareAndSet(this, current, (int) batchSize)) { break; } else { continue; @@ -465,10 +578,10 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { } public void incrementRunningCount() { - long val = runningCountUpdater.incrementAndGet(this); + int val = runningCountUpdater.incrementAndGet(this); for (;;) { - long max = concurrentMaxUpdater.get(this); + int max = concurrentMaxUpdater.get(this); if (val > max) { if (concurrentMaxUpdater.compareAndSet(this, max, val)) { break; @@ -497,7 +610,51 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { addExecuteTime(nanoSpan); if (StatementExecuteType.ExecuteQuery != executeType && !firstResultSet) { - executeAndResultHoldTimeHistogram.record((nanoSpan) / 1000 / 1000); + executeAndResultHoldTimeHistogramRecord(nanoSpan); + } + } + + private void executeAndResultHoldTimeHistogramRecord(long nanoSpan) { + long millis = nanoSpan / 1000 / 1000; + + if (millis < 1) { + executeAndResultHoldTime_0_1_Updater.incrementAndGet(this); + } else if (millis < 10) { + executeAndResultHoldTime_1_10_Updater.incrementAndGet(this); + } else if (millis < 100) { + executeAndResultHoldTime_10_100_Updater.incrementAndGet(this); + } else if (millis < 1000) { + executeAndResultHoldTime_100_1000_Updater.incrementAndGet(this); + } else if (millis < 10000) { + executeAndResultHoldTime_1000_10000_Updater.incrementAndGet(this); + } else if (millis < 100000) { + executeAndResultHoldTime_10000_100000_Updater.incrementAndGet(this); + } else if (millis < 1000000) { + executeAndResultHoldTime_100000_1000000_Updater.incrementAndGet(this); + } else { + executeAndResultHoldTime_1000000_more_Updater.incrementAndGet(this); + } + } + + private void histogramRecord(long nanoSpan) { + long millis = nanoSpan / 1000 / 1000; + + if (millis < 1) { + histogram_0_1_Updater.incrementAndGet(this); + } else if (millis < 10) { + histogram_1_10_Updater.incrementAndGet(this); + } else if (millis < 100) { + histogram_10_100_Updater.incrementAndGet(this); + } else if (millis < 1000) { + histogram_100_1000_Updater.incrementAndGet(this); + } else if (millis < 10000) { + histogram_1000_10000_Updater.incrementAndGet(this); + } else if (millis < 100000) { + histogram_10000_100000_Updater.incrementAndGet(this); + } else if (millis < 1000000) { + histogram_100000_1000000_Updater.incrementAndGet(this); + } else { + histogram_1000000_more_Updater.incrementAndGet(this); } } @@ -521,7 +678,7 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { } long millis = nanoSpan / (1000 * 1000); - histogram.record(millis); + histogramRecord(millis); } public long getExecuteMillisTotal() { @@ -735,14 +892,14 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { map.put("URL", null); // 23 map.put("InTransactionCount", getInTransactionCount()); // 24 - map.put("Histogram", this.histogram.toArray()); // 25 + map.put("Histogram", this.getHistogramValues()); // 25 map.put("LastSlowParameters", lastSlowParameters); // 26 map.put("ResultSetHoldTime", getResultSetHoldTimeMilis()); // 27 map.put("ExecuteAndResultSetHoldTime", this.getExecuteAndResultSetHoldTimeMilis()); // 28 - map.put("FetchRowCountHistogram", this.getFetchRowCountHistogram().toArray()); // 29 + map.put("FetchRowCountHistogram", this.getFetchRowCountHistogramValues()); // 29 - map.put("EffectedRowCountHistogram", this.getUpdateCountHistogram().toArray()); // 30 - map.put("ExecuteAndResultHoldTimeHistogram", this.getExecuteAndResultHoldTimeHistogram().toArray()); // 31 + map.put("EffectedRowCountHistogram", this.getUpdateCountHistogramValues()); // 30 + map.put("ExecuteAndResultHoldTimeHistogram", this.getExecuteAndResultHoldTimeHistogramValues()); // 31 map.put("EffectedRowCountMax", getUpdateCountMax()); // 32 map.put("FetchRowCountMax", getFetchRowCountMax()); // 33 map.put("ClobOpenCount", getClobOpenCount()); // 34 @@ -756,8 +913,27 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { return map; } - public Histogram getHistogram() { - return this.histogram; + public long[] getHistogramValues() { + return new long[] { + // + histogram_0_1, // + histogram_1_10, // + histogram_10_100, // + histogram_100_1000, // + histogram_1000_10000, // + histogram_10000_100000, // + histogram_100000_1000000, // + histogram_1000000_more // + }; + } + + public long getHistogramSum() { + long[] values = this.getHistogramValues(); + long sum = 0; + for (int i = 0; i < values.length; ++i) { + sum += values[i]; + } + return sum; } public CompositeDataSupport getCompositeData() throws JMException { @@ -783,16 +959,51 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { return getExecuteAndResultSetHoldTimeNano() / (1000 * 1000); } - public Histogram getFetchRowCountHistogram() { - return this.fetchRowCountHistogram; + public long[] getFetchRowCountHistogramValues() { + return new long[] { + // + fetchRowCount_0_1, // + fetchRowCount_1_10, // + fetchRowCount_10_100, // + fetchRowCount_100_1000, // + fetchRowCount_1000_10000, // + fetchRowCount_10000_more // + }; } - public Histogram getUpdateCountHistogram() { - return this.updateCountHistogram; + public long[] getUpdateCountHistogramValues() { + return new long[] { + // + updateCount_0_1, // + updateCount_1_10, // + updateCount_10_100, // + updateCount_100_1000, // + updateCount_1000_10000, // + updateCount_10000_more // + }; } - public Histogram getExecuteAndResultHoldTimeHistogram() { - return this.executeAndResultHoldTimeHistogram; + public long[] getExecuteAndResultHoldTimeHistogramValues() { + return new long[] { + // + executeAndResultHoldTime_0_1, // + executeAndResultHoldTime_1_10, // + executeAndResultHoldTime_10_100, // + executeAndResultHoldTime_100_1000, // + executeAndResultHoldTime_1000_10000, // + executeAndResultHoldTime_10000_100000, // + executeAndResultHoldTime_100000_1000000, // + executeAndResultHoldTime_1000000_more // + }; + } + + public long getExecuteAndResultHoldTimeHistogramSum() { + long[] values = this.getExecuteAndResultHoldTimeHistogramValues(); + long sum = 0; + for (int i = 0; i < values.length; ++i) { + sum += values[i]; + } + return sum; } public long getResultSetHoldTimeNano() { @@ -810,8 +1021,8 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean { public void addResultSetHoldTimeNano(long statementExecuteNano, long resultHoldTimeNano) { resultSetHoldTimeNanoUpdater.addAndGet(this, resultHoldTimeNano); executeAndResultSetHoldTimeUpdater.addAndGet(this, statementExecuteNano + resultHoldTimeNano); - executeAndResultHoldTimeHistogram.record((statementExecuteNano + resultHoldTimeNano) / 1000 / 1000); - updateCountHistogram.record(0); + executeAndResultHoldTimeHistogramRecord((statementExecuteNano + resultHoldTimeNano) / 1000 / 1000); + updateCount_0_1_Updater.incrementAndGet(this); } public boolean isRemoved() { diff --git a/src/main/java/com/alibaba/druid/support/http/WebStatFilter.java b/src/main/java/com/alibaba/druid/support/http/WebStatFilter.java index baf8b465f6..f594a7848f 100644 --- a/src/main/java/com/alibaba/druid/support/http/WebStatFilter.java +++ b/src/main/java/com/alibaba/druid/support/http/WebStatFilter.java @@ -229,14 +229,7 @@ public class WebStatFilter implements Filter { String ip = DruidWebUtils.getRemoteAddr(request); - int addressCount = sessionStat.getRemoteAddresses().size(); - if (addressCount < 10) { - sessionStat.addRemoteAddress(ip); - } else { - if (!sessionStat.getRemoteAddress().contains(ip)) { - LOG.error("sessoin ip change too many"); - } - } + sessionStat.addRemoteAddress(ip); } return sessionStat; diff --git a/src/main/java/com/alibaba/druid/support/http/stat/WebSessionStat.java b/src/main/java/com/alibaba/druid/support/http/stat/WebSessionStat.java index 320207bb6c..0a5fc3eaa3 100644 --- a/src/main/java/com/alibaba/druid/support/http/stat/WebSessionStat.java +++ b/src/main/java/com/alibaba/druid/support/http/stat/WebSessionStat.java @@ -16,67 +16,95 @@ package com.alibaba.druid.support.http.stat; import java.util.Date; -import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Map; -import java.util.Set; import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; import java.util.concurrent.atomic.AtomicLongFieldUpdater; -import com.alibaba.druid.util.Histogram; +import com.alibaba.druid.support.logging.Log; +import com.alibaba.druid.support.logging.LogFactory; public class WebSessionStat { + private final static Log LOG = LogFactory.getLog(WebSessionStat.class); + private final String sessionId; private volatile int runningCount; private volatile int concurrentMax; - final static AtomicIntegerFieldUpdater runningCountUpdater = AtomicIntegerFieldUpdater.newUpdater(WebSessionStat.class, - "runningCount"); - final static AtomicIntegerFieldUpdater concurrentMaxUpdater = AtomicIntegerFieldUpdater.newUpdater(WebSessionStat.class, - "concurrentMax"); + final static AtomicIntegerFieldUpdater runningCountUpdater = AtomicIntegerFieldUpdater.newUpdater(WebSessionStat.class, + "runningCount"); + final static AtomicIntegerFieldUpdater concurrentMaxUpdater = AtomicIntegerFieldUpdater.newUpdater(WebSessionStat.class, + "concurrentMax"); private volatile long requestCount; private volatile long requestErrorCount; private volatile long requestTimeNano; - final static AtomicLongFieldUpdater requestCountUpdater = AtomicLongFieldUpdater.newUpdater(WebSessionStat.class, - "requestCount"); - final static AtomicLongFieldUpdater requestErrorCountUpdater = AtomicLongFieldUpdater.newUpdater(WebSessionStat.class, - "requestErrorCount"); - final static AtomicLongFieldUpdater requestTimeNanoUpdater = AtomicLongFieldUpdater.newUpdater(WebSessionStat.class, - "requestTimeNano"); + final static AtomicLongFieldUpdater requestCountUpdater = AtomicLongFieldUpdater.newUpdater(WebSessionStat.class, + "requestCount"); + final static AtomicLongFieldUpdater requestErrorCountUpdater = AtomicLongFieldUpdater.newUpdater(WebSessionStat.class, + "requestErrorCount"); + final static AtomicLongFieldUpdater requestTimeNanoUpdater = AtomicLongFieldUpdater.newUpdater(WebSessionStat.class, + "requestTimeNano"); private volatile long jdbcFetchRowCount; private volatile long jdbcUpdateCount; private volatile long jdbcExecuteCount; private volatile long jdbcExecuteTimeNano; - final static AtomicLongFieldUpdater jdbcFetchRowCountUpdater = AtomicLongFieldUpdater.newUpdater(WebSessionStat.class, - "jdbcFetchRowCount"); - final static AtomicLongFieldUpdater jdbcUpdateCountUpdater = AtomicLongFieldUpdater.newUpdater(WebSessionStat.class, - "jdbcUpdateCount"); - final static AtomicLongFieldUpdater jdbcExecuteCountUpdater = AtomicLongFieldUpdater.newUpdater(WebSessionStat.class, - "jdbcExecuteCount"); - final static AtomicLongFieldUpdater jdbcExecuteTimeNanoUpdater = AtomicLongFieldUpdater.newUpdater(WebSessionStat.class, - "jdbcExecuteTimeNano"); + final static AtomicLongFieldUpdater jdbcFetchRowCountUpdater = AtomicLongFieldUpdater.newUpdater(WebSessionStat.class, + "jdbcFetchRowCount"); + final static AtomicLongFieldUpdater jdbcUpdateCountUpdater = AtomicLongFieldUpdater.newUpdater(WebSessionStat.class, + "jdbcUpdateCount"); + final static AtomicLongFieldUpdater jdbcExecuteCountUpdater = AtomicLongFieldUpdater.newUpdater(WebSessionStat.class, + "jdbcExecuteCount"); + final static AtomicLongFieldUpdater jdbcExecuteTimeNanoUpdater = AtomicLongFieldUpdater.newUpdater(WebSessionStat.class, + "jdbcExecuteTimeNano"); private volatile long jdbcCommitCount; private volatile long jdbcRollbackCount; - final static AtomicLongFieldUpdater jdbcCommitCountUpdater = AtomicLongFieldUpdater.newUpdater(WebSessionStat.class, - "jdbcCommitCount"); - final static AtomicLongFieldUpdater jdbcRollbackCountUpdater = AtomicLongFieldUpdater.newUpdater(WebSessionStat.class, - "jdbcRollbackCount"); + final static AtomicLongFieldUpdater jdbcCommitCountUpdater = AtomicLongFieldUpdater.newUpdater(WebSessionStat.class, + "jdbcCommitCount"); + final static AtomicLongFieldUpdater jdbcRollbackCountUpdater = AtomicLongFieldUpdater.newUpdater(WebSessionStat.class, + "jdbcRollbackCount"); - private long createTimeMillis = -1L; - private volatile long lastAccessTimeMillis = -1L; + private long createTimeMillis = -1L; + private volatile long lastAccessTimeMillis = -1L; - private Set remoteAddresses = new HashSet(2); + private String remoteAddresses; - private String principal = null; + private String principal = null; private String userAgent; - private Histogram requestIntervalHistogram = Histogram.makeHistogram(8); + private volatile int requestIntervalHistogram_0_1; + private volatile int requestIntervalHistogram_1_10; + private volatile int requestIntervalHistogram_10_100; + private volatile int requestIntervalHistogram_100_1000; + private volatile int requestIntervalHistogram_1000_10000; + private volatile int requestIntervalHistogram_10000_100000; + private volatile int requestIntervalHistogram_100000_1000000; + private volatile int requestIntervalHistogram_1000000_10000000; + private volatile int requestIntervalHistogram_10000000_more; + + final static AtomicIntegerFieldUpdater requestIntervalHistogram_0_1_Updater = AtomicIntegerFieldUpdater.newUpdater(WebSessionStat.class, + "requestIntervalHistogram_0_1"); + final static AtomicIntegerFieldUpdater requestIntervalHistogram_1_10_Updater = AtomicIntegerFieldUpdater.newUpdater(WebSessionStat.class, + "requestIntervalHistogram_1_10"); + final static AtomicIntegerFieldUpdater requestIntervalHistogram_10_100_Updater = AtomicIntegerFieldUpdater.newUpdater(WebSessionStat.class, + "requestIntervalHistogram_10_100"); + final static AtomicIntegerFieldUpdater requestIntervalHistogram_100_1000_Updater = AtomicIntegerFieldUpdater.newUpdater(WebSessionStat.class, + "requestIntervalHistogram_100_1000"); + final static AtomicIntegerFieldUpdater requestIntervalHistogram_1000_10000_Updater = AtomicIntegerFieldUpdater.newUpdater(WebSessionStat.class, + "requestIntervalHistogram_1000_10000"); + final static AtomicIntegerFieldUpdater requestIntervalHistogram_10000_100000_Updater = AtomicIntegerFieldUpdater.newUpdater(WebSessionStat.class, + "requestIntervalHistogram_10000_100000"); + final static AtomicIntegerFieldUpdater requestIntervalHistogram_100000_1000000_Updater = AtomicIntegerFieldUpdater.newUpdater(WebSessionStat.class, + "requestIntervalHistogram_100000_1000000"); + final static AtomicIntegerFieldUpdater requestIntervalHistogram_1000000_10000000_Updater = AtomicIntegerFieldUpdater.newUpdater(WebSessionStat.class, + "requestIntervalHistogram_1000000_10000000"); + final static AtomicIntegerFieldUpdater requestIntervalHistogram_10000000_more_Updater = AtomicIntegerFieldUpdater.newUpdater(WebSessionStat.class, + "requestIntervalHistogram_10000000_more"); public WebSessionStat(String sessionId){ super(); @@ -96,10 +124,18 @@ public class WebSessionStat { jdbcCommitCountUpdater.set(this, 0); jdbcRollbackCountUpdater.set(this, 0); - remoteAddresses.clear(); + remoteAddresses = null; principal = null; - requestIntervalHistogram.reset(); + requestIntervalHistogram_0_1_Updater.set(this, 0); + requestIntervalHistogram_1_10_Updater.set(this, 0); + requestIntervalHistogram_10_100_Updater.set(this, 0); + requestIntervalHistogram_100_1000_Updater.set(this, 0); + requestIntervalHistogram_1000_10000_Updater.set(this, 0); + requestIntervalHistogram_10000_100000_Updater.set(this, 0); + requestIntervalHistogram_100000_1000000_Updater.set(this, 0); + requestIntervalHistogram_1000000_10000000_Updater.set(this, 0); + requestIntervalHistogram_10000000_more_Updater.set(this, 0); } public String getUserAgent() { @@ -150,38 +186,42 @@ public class WebSessionStat { return new Date(lastAccessTimeMillis); } - public Set getRemoteAddresses() { - return remoteAddresses; - } - public String getRemoteAddress() { - if (remoteAddresses.size() == 0) { - return null; - } - - if (remoteAddresses.size() == 1) { - return remoteAddresses.iterator().next(); - } - - StringBuilder buf = new StringBuilder(); - for (String item : remoteAddresses) { - if (buf.length() != 0) { - buf.append(";"); - } - buf.append(item); - } - - return buf.toString(); + return remoteAddresses; } public void setLastAccessTimeMillis(long lastAccessTimeMillis) { if (this.lastAccessTimeMillis > 0) { long interval = lastAccessTimeMillis - this.lastAccessTimeMillis; - requestIntervalHistogram.record(interval); + requestIntervalHistogramRecord(interval); } this.lastAccessTimeMillis = lastAccessTimeMillis; } + private void requestIntervalHistogramRecord(long nanoSpan) { + long millis = nanoSpan / 1000 / 1000; + + if (millis < 1) { + requestIntervalHistogram_0_1_Updater.incrementAndGet(this); + } else if (millis < 10) { + requestIntervalHistogram_1_10_Updater.incrementAndGet(this); + } else if (millis < 100) { + requestIntervalHistogram_10_100_Updater.incrementAndGet(this); + } else if (millis < 1000) { + requestIntervalHistogram_100_1000_Updater.incrementAndGet(this); + } else if (millis < 10000) { + requestIntervalHistogram_1000_10000_Updater.incrementAndGet(this); + } else if (millis < 100000) { + requestIntervalHistogram_10000_100000_Updater.incrementAndGet(this); + } else if (millis < 1000000) { + requestIntervalHistogram_100000_1000000_Updater.incrementAndGet(this); + } else if (millis < 10000000) { + requestIntervalHistogram_1000000_10000000_Updater.incrementAndGet(this); + } else { + requestIntervalHistogram_10000000_more_Updater.incrementAndGet(this); + } + } + public void beforeInvoke() { int running = runningCountUpdater.incrementAndGet(this); @@ -230,7 +270,21 @@ public class WebSessionStat { } public void addRemoteAddress(String ip) { - this.remoteAddresses.add(ip); + if (remoteAddresses == null) { + this.remoteAddresses = ip; + return; + } + + if (remoteAddresses.contains(ip)) { + return; + } + + if (remoteAddresses.length() > 256) { + LOG.error("sessoin ip change too many"); + return; + } + + remoteAddresses += ';' + ip; } public int getRunningCount() { @@ -322,7 +376,18 @@ public class WebSessionStat { } public long[] getRequestInterval() { - return requestIntervalHistogram.toArray(); + return new long[] { + // + requestIntervalHistogram_0_1, // + requestIntervalHistogram_1_10, // + requestIntervalHistogram_10_100, // + requestIntervalHistogram_100_1000, // + requestIntervalHistogram_1000_10000, // + requestIntervalHistogram_10000_100000, // + requestIntervalHistogram_100000_1000000, // + requestIntervalHistogram_1000000_10000000, // + requestIntervalHistogram_10000000_more // + }; } public Map getStatData() { diff --git a/src/main/java/com/alibaba/druid/support/profile/ProfileStat.java b/src/main/java/com/alibaba/druid/support/profile/ProfileStat.java index c9a3de9b49..e99b9f90c2 100644 --- a/src/main/java/com/alibaba/druid/support/profile/ProfileStat.java +++ b/src/main/java/com/alibaba/druid/support/profile/ProfileStat.java @@ -5,10 +5,12 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; public class ProfileStat { + private ConcurrentHashMap entries = new ConcurrentHashMap( + 4, + 0.75f, + 1); - private ConcurrentHashMap entries = new ConcurrentHashMap(); - - public ConcurrentHashMap getEntries() { + public Map getEntries() { return entries; } @@ -16,7 +18,7 @@ public class ProfileStat { if (requestStatsMap == null) { return; } - + for (Map.Entry entry : requestStatsMap.entrySet()) { ProfileEntryKey entryKey = entry.getKey(); ProfileEntryReqStat reqEntryStat = entry.getValue(); diff --git a/src/test/java/com/alibaba/druid/bvt/filter/StatFilterAfterResetTest.java b/src/test/java/com/alibaba/druid/bvt/filter/StatFilterAfterResetTest.java index ea2d5773d8..e03cc7b530 100644 --- a/src/test/java/com/alibaba/druid/bvt/filter/StatFilterAfterResetTest.java +++ b/src/test/java/com/alibaba/druid/bvt/filter/StatFilterAfterResetTest.java @@ -64,20 +64,17 @@ public class StatFilterAfterResetTest extends TestCase { sqlStat = dataSource.getDataSourceStat().getSqlStat(sql); Assert.assertNotNull(sqlStat); - Histogram histogram = sqlStat.getExecuteAndResultHoldTimeHistogram(); - Assert.assertEquals("first failed", 1, - histogram.getSum()); + Assert.assertEquals("first failed", 1, sqlStat.getExecuteAndResultHoldTimeHistogramSum()); rs.close(); - Assert.assertEquals("second failed", 1, - histogram.getSum()); + Assert.assertEquals("second failed", 1, sqlStat.getExecuteAndResultHoldTimeHistogramSum()); stmt.close(); conn.close(); - Assert.assertEquals(1, histogram.getSum()); + Assert.assertEquals(1, sqlStat.getExecuteAndResultHoldTimeHistogramSum()); } JdbcStatManager.getInstance().reset(); @@ -97,15 +94,13 @@ public class StatFilterAfterResetTest extends TestCase { } Assert.assertNotSame(sqlStat, dataSource.getDataSourceStat().getSqlStat(sql)); - + { - Histogram histogram = sqlStat.getExecuteAndResultHoldTimeHistogram(); - Assert.assertEquals(0, histogram.getValue(0) + histogram.getValue(1) + histogram.getValue(2)); + Assert.assertEquals(0, sqlStat.getExecuteAndResultHoldTimeHistogramSum()); } - + sqlStat = dataSource.getDataSourceStat().getSqlStat(sql); - - Histogram histogram = sqlStat.getExecuteAndResultHoldTimeHistogram(); - Assert.assertEquals(1, histogram.getValue(0) + histogram.getValue(1) + histogram.getValue(2)); + + Assert.assertEquals(1, sqlStat.getExecuteAndResultHoldTimeHistogramSum()); } } diff --git a/src/test/java/com/alibaba/druid/bvt/filter/StatFilterExecuteFirstResultSetTest.java b/src/test/java/com/alibaba/druid/bvt/filter/StatFilterExecuteFirstResultSetTest.java index 84a9049054..7002b27692 100644 --- a/src/test/java/com/alibaba/druid/bvt/filter/StatFilterExecuteFirstResultSetTest.java +++ b/src/test/java/com/alibaba/druid/bvt/filter/StatFilterExecuteFirstResultSetTest.java @@ -79,12 +79,10 @@ public class StatFilterExecuteFirstResultSetTest extends TestCase { JdbcSqlStat sqlStat = dataSource.getDataSourceStat().getSqlStat(sql); - Histogram histogram = sqlStat.getHistogram(); - Assert.assertEquals(1, histogram.getSum()); + Assert.assertEquals(1, sqlStat.getHistogramSum()); - Histogram rsHoldHistogram = sqlStat.getExecuteAndResultHoldTimeHistogram(); - Assert.assertEquals(1, rsHoldHistogram.getSum()); + Assert.assertEquals(1, sqlStat.getExecuteAndResultHoldTimeHistogramSum()); } static class MyMockPreparedStatement extends MockPreparedStatement { diff --git a/src/test/java/com/alibaba/druid/bvt/filter/StatFilterExecuteTest.java b/src/test/java/com/alibaba/druid/bvt/filter/StatFilterExecuteTest.java index 4444983184..546ae1acf3 100644 --- a/src/test/java/com/alibaba/druid/bvt/filter/StatFilterExecuteTest.java +++ b/src/test/java/com/alibaba/druid/bvt/filter/StatFilterExecuteTest.java @@ -67,7 +67,7 @@ public class StatFilterExecuteTest extends TestCase { PreparedStatement stmt = conn.prepareStatement(sql); - Assert.assertEquals(0, dataSource.getDataSourceStat().getSqlStat(sql).getExecuteAndResultHoldTimeHistogram().getSum()); + Assert.assertEquals(0, dataSource.getDataSourceStat().getSqlStat(sql).getExecuteAndResultHoldTimeHistogramSum()); boolean firstResult = stmt.execute(); Assert.assertFalse(firstResult); @@ -78,12 +78,9 @@ public class StatFilterExecuteTest extends TestCase { JdbcSqlStat sqlStat = dataSource.getDataSourceStat().getSqlStat(sql); - Histogram histogram = sqlStat.getHistogram(); - Assert.assertEquals(1, histogram.getSum()); + Assert.assertEquals(1, sqlStat.getHistogramSum()); - Histogram rsHoldHistogram = sqlStat.getExecuteAndResultHoldTimeHistogram(); - - Assert.assertEquals(1, rsHoldHistogram.getSum()); + Assert.assertEquals(1, sqlStat.getExecuteAndResultHoldTimeHistogramSum()); } static class MyMockPreparedStatement extends MockPreparedStatement { diff --git a/src/test/java/com/alibaba/druid/bvt/filter/StatFilterResultSetMultiCloseTest.java b/src/test/java/com/alibaba/druid/bvt/filter/StatFilterResultSetMultiCloseTest.java index 1ef68880e8..948a7efd22 100644 --- a/src/test/java/com/alibaba/druid/bvt/filter/StatFilterResultSetMultiCloseTest.java +++ b/src/test/java/com/alibaba/druid/bvt/filter/StatFilterResultSetMultiCloseTest.java @@ -66,17 +66,16 @@ public class StatFilterResultSetMultiCloseTest extends TestCase { sqlStat = dataSource.getDataSourceStat().getSqlStat(sql); Assert.assertNotNull(sqlStat); - Histogram histogram = sqlStat.getExecuteAndResultHoldTimeHistogram(); - Assert.assertEquals("first failed", 1, histogram.getValue(0) + histogram.getValue(1) + histogram.getValue(2)); + Assert.assertEquals("first failed", 1, sqlStat.getExecuteAndResultHoldTimeHistogramSum()); rs.close(); - Assert.assertEquals("second failed", 1, histogram.getValue(0) + histogram.getValue(1) + histogram.getValue(2)); + Assert.assertEquals("second failed", 1, sqlStat.getExecuteAndResultHoldTimeHistogramSum()); stmt.close(); conn.close(); - Assert.assertEquals(1, histogram.getValue(0) + histogram.getValue(1) + histogram.getValue(2)); + Assert.assertEquals(1, sqlStat.getExecuteAndResultHoldTimeHistogramSum()); } } diff --git a/src/test/java/com/alibaba/druid/stat/AtomicMemoryTest.java b/src/test/java/com/alibaba/druid/stat/AtomicMemoryTest.java new file mode 100644 index 0000000000..99b9514caf --- /dev/null +++ b/src/test/java/com/alibaba/druid/stat/AtomicMemoryTest.java @@ -0,0 +1,33 @@ +package com.alibaba.druid.stat; + +import java.lang.management.ManagementFactory; +import java.text.NumberFormat; +import java.util.concurrent.atomic.AtomicLong; + +import junit.framework.TestCase; + +public class AtomicMemoryTest extends TestCase { + + public void test_0() throws Exception { + AtomicLong item = new AtomicLong(); + gc(); + long memoryStart = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed(); + + final int COUNT = 1024 * 1024; + AtomicLong[] items = new AtomicLong[COUNT]; + for (int i = 0; i < COUNT; ++i) { + items[i] = new AtomicLong(); + // items[i] = Histogram.makeHistogram(20); + } + + long memoryEnd = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed(); + + System.out.println("memory used : " + NumberFormat.getInstance().format(memoryEnd - memoryStart)); + } + + private void gc() { + for (int i = 0; i < 10; ++i) { + System.gc(); + } + } +} diff --git a/src/test/java/com/alibaba/druid/stat/HashMapMemoryTest.java b/src/test/java/com/alibaba/druid/stat/HashMapMemoryTest.java new file mode 100644 index 0000000000..8f12624717 --- /dev/null +++ b/src/test/java/com/alibaba/druid/stat/HashMapMemoryTest.java @@ -0,0 +1,34 @@ +package com.alibaba.druid.stat; + +import java.lang.management.ManagementFactory; +import java.text.NumberFormat; +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +public class HashMapMemoryTest extends TestCase { + + public void test_0() throws Exception { + HashMap item = new HashMap(); + gc(); + long memoryStart = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed(); + + final int COUNT = 1024 * 1024; + Map[] items = new Map[COUNT]; + for (int i = 0; i < COUNT; ++i) { + items[i] = new HashMap(); + // items[i] = Histogram.makeHistogram(20); + } + + long memoryEnd = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed(); + + System.out.println("memory used : " + NumberFormat.getInstance().format(memoryEnd - memoryStart)); + } + + private void gc() { + for (int i = 0; i < 10; ++i) { + System.gc(); + } + } +} diff --git a/src/test/java/com/alibaba/druid/stat/JdbcSqlStatTest.java b/src/test/java/com/alibaba/druid/stat/JdbcSqlStatTest.java new file mode 100644 index 0000000000..ef6f196b0c --- /dev/null +++ b/src/test/java/com/alibaba/druid/stat/JdbcSqlStatTest.java @@ -0,0 +1,33 @@ +package com.alibaba.druid.stat; + +import java.lang.management.ManagementFactory; +import java.text.NumberFormat; + +import junit.framework.TestCase; + +public class JdbcSqlStatTest extends TestCase { + private JdbcSqlStat item; + + public void test_0() throws Exception { + item = new JdbcSqlStat(""); + gc(); + long memoryStart = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed(); + + final int COUNT = 1024 * 1024; + JdbcSqlStat[] items = new JdbcSqlStat[COUNT]; + for (int i = 0; i < COUNT; ++i) { + items[i] = new JdbcSqlStat(""); + // items[i] = Histogram.makeHistogram(20); + } + + long memoryEnd = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed(); + + System.out.println("memory used : " + NumberFormat.getInstance().format(memoryEnd - memoryStart)); + } + + private void gc() { + for (int i = 0; i < 10; ++i) { + System.gc(); + } + } +} diff --git a/src/test/java/com/alibaba/druid/stat/MemoryTest.java b/src/test/java/com/alibaba/druid/stat/MemoryTest.java new file mode 100644 index 0000000000..ce62be4cfb --- /dev/null +++ b/src/test/java/com/alibaba/druid/stat/MemoryTest.java @@ -0,0 +1,38 @@ +package com.alibaba.druid.stat; + +import java.lang.management.ManagementFactory; +import java.text.NumberFormat; +import java.util.concurrent.atomic.AtomicLong; + +import junit.framework.TestCase; + +public class MemoryTest extends TestCase { + + public void test_0() throws Exception { + A item = new A(); + gc(); + final int COUNT = 1024 * 1024; + A[] items = new A[COUNT]; + + long memoryStart = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed(); + + for (int i = 0; i < COUNT; ++i) { + items[i] = new A(); + // items[i] = Histogram.makeHistogram(20); + } + + long memoryEnd = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed(); + + System.out.println("memory used : " + NumberFormat.getInstance().format(memoryEnd - memoryStart)); + } + + private void gc() { + for (int i = 0; i < 10; ++i) { + System.gc(); + } + } + + public static class A { + private volatile long v; + } +} diff --git a/src/test/java/com/alibaba/druid/stat/PerfTest.java b/src/test/java/com/alibaba/druid/stat/PerfTest.java new file mode 100644 index 0000000000..0810b858eb --- /dev/null +++ b/src/test/java/com/alibaba/druid/stat/PerfTest.java @@ -0,0 +1,56 @@ +package com.alibaba.druid.stat; + +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicLongFieldUpdater; + +import junit.framework.TestCase; + +public class PerfTest extends TestCase { + + public void test_0() throws Exception { + for (int i = 0; i < 3; ++i) { + long startMillis = System.currentTimeMillis(); + a(); + long millis = System.currentTimeMillis() - startMillis; + System.out.println("a : " + millis); + } + } + + private void a() { + A a = new A(); + for (int i = 0; i < 1000 * 1000 * 1000; ++i) { + a.incrementAndGet(); + } + } + + private void b() { + B b = new B(); + for (int i = 0; i < 1000 * 1000 * 1000; ++i) { + b.incrementAndGet(); + } + } + + public static class A { + + private volatile long value; + + static final AtomicLongFieldUpdater updater = AtomicLongFieldUpdater.newUpdater(A.class, "value"); + + public long incrementAndGet() { + return updater.incrementAndGet(this); + } + + public long getValue() { + return value; + } + } + + public static class B { + + private final AtomicLong value = new AtomicLong(); + + public long incrementAndGet() { + return value.incrementAndGet(); + } + } +} diff --git a/src/test/java/com/alibaba/druid/stat/WebSessionStatTest.java b/src/test/java/com/alibaba/druid/stat/WebSessionStatTest.java new file mode 100644 index 0000000000..43125d5af4 --- /dev/null +++ b/src/test/java/com/alibaba/druid/stat/WebSessionStatTest.java @@ -0,0 +1,34 @@ +package com.alibaba.druid.stat; + +import java.lang.management.ManagementFactory; +import java.text.NumberFormat; + +import junit.framework.TestCase; + +import com.alibaba.druid.support.http.stat.WebSessionStat; + +public class WebSessionStatTest extends TestCase { + + public void test_0() throws Exception { + WebSessionStat item = new WebSessionStat("1b959a6db8489c4c7ef7bf0bd743ab52"); + gc(); + long memoryStart = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed(); + + final int COUNT = 1024 * 1024; + WebSessionStat[] items = new WebSessionStat[COUNT]; + for (int i = 0; i < COUNT; ++i) { + items[i] = new WebSessionStat(""); + // items[i] = Histogram.makeHistogram(20); + } + + long memoryEnd = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed(); + + System.out.println("memory used : " + NumberFormat.getInstance().format(memoryEnd - memoryStart)); + } + + private void gc() { + for (int i = 0; i < 10; ++i) { + System.gc(); + } + } +} diff --git a/src/test/java/com/alibaba/druid/stat/WebURIStatMemoryTest.java b/src/test/java/com/alibaba/druid/stat/WebURIStatMemoryTest.java new file mode 100644 index 0000000000..260d5d8401 --- /dev/null +++ b/src/test/java/com/alibaba/druid/stat/WebURIStatMemoryTest.java @@ -0,0 +1,35 @@ +package com.alibaba.druid.stat; + +import java.lang.management.ManagementFactory; +import java.text.NumberFormat; + +import junit.framework.TestCase; + +import com.alibaba.druid.support.http.stat.WebURIStat; + +public class WebURIStatMemoryTest extends TestCase { + + public void test_0() throws Exception { + WebURIStat item = new WebURIStat(""); + gc(); + long memoryStart = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed(); + + final int COUNT = 1024 * 1024; + WebURIStat[] items = new WebURIStat[COUNT]; + for (int i = 0; i < COUNT; ++i) { + items[i] = new WebURIStat(""); + items[i].getProfiletat(); + // items[i] = Histogram.makeHistogram(20); + } + + long memoryEnd = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed(); + + System.out.println("memory used : " + NumberFormat.getInstance().format(memoryEnd - memoryStart)); + } + + private void gc() { + for (int i = 0; i < 10; ++i) { + System.gc(); + } + } +}