Merge pull request #165 from wenshao/master

use AtomicLongFieldUpdater instead of AtomicLong
This commit is contained in:
温高铁
2012-10-07 05:59:16 -07:00
4 changed files with 380 additions and 248 deletions
@@ -18,7 +18,7 @@ package com.alibaba.druid.stat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
import javax.management.JMException;
import javax.management.openmbean.ArrayType;
@@ -38,70 +38,129 @@ 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 final AtomicLong executeBatchSizeTotal = new AtomicLong();
private final AtomicLong executeBatchSizeMax = new AtomicLong();
private volatile long executeBatchSizeTotal;
private volatile long executeBatchSizeMax;
private final AtomicLong executeSuccessCount = new AtomicLong();
private final AtomicLong executeSpanNanoTotal = new AtomicLong();
private final AtomicLong executeSpanNanoMax = new AtomicLong();
private final AtomicLong runningCount = new AtomicLong(0L);
private final AtomicLong concurrentMax = new AtomicLong();
private final AtomicLong resultSetHoldTimeNano = new AtomicLong();
private final AtomicLong executeAndResultSetHoldTime = new AtomicLong();
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 String name;
private String file;
private String dbType;
final static AtomicLongFieldUpdater<JdbcSqlStat> executeBatchSizeTotalUpdater;
final static AtomicLongFieldUpdater<JdbcSqlStat> executeBatchSizeMaxUpdater;
final static AtomicLongFieldUpdater<JdbcSqlStat> executeSuccessCountUpdater;
final static AtomicLongFieldUpdater<JdbcSqlStat> executeSpanNanoTotalUpdater;
final static AtomicLongFieldUpdater<JdbcSqlStat> executeSpanNanoMaxUpdater;
final static AtomicLongFieldUpdater<JdbcSqlStat> runningCountUpdater;
final static AtomicLongFieldUpdater<JdbcSqlStat> concurrentMaxUpdater;
final static AtomicLongFieldUpdater<JdbcSqlStat> resultSetHoldTimeNanoUpdater;
final static AtomicLongFieldUpdater<JdbcSqlStat> 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");
}
private long executeNanoSpanMaxOccurTime;
private String name;
private String file;
private String dbType;
private final AtomicLong executeErrorCount = new AtomicLong();
private Throwable executeErrorLast;
private long executeErrorLastTime;
private long executeNanoSpanMaxOccurTime;
private final AtomicLong updateCount = new AtomicLong();
private final AtomicLong updateCountMax = new AtomicLong();
private final AtomicLong fetchRowCount = new AtomicLong();
private final AtomicLong fetchRowCountMax = new AtomicLong();
private volatile long executeErrorCount;
private Throwable executeErrorLast;
private long executeErrorLastTime;
private final AtomicLong inTransactionCount = new AtomicLong();
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 String lastSlowParameters;
private final AtomicLong clobOpenCount = new AtomicLong();
private final AtomicLong blobOpenCount = new AtomicLong();
private final AtomicLong readStringLength = new AtomicLong();
private final AtomicLong readBytesLength = new AtomicLong();
private boolean removed = false;
private final AtomicLong inputStreamOpenCount = new AtomicLong();
private final AtomicLong readerOpenCount = new AtomicLong();
private volatile long clobOpenCount;
private volatile long blobOpenCount;
private volatile long readStringLength;
private volatile long readBytesLength;
private final Histogram histogram = new Histogram(new long[] { //
//
private volatile long inputStreamOpenCount;
private volatile long readerOpenCount;
final static AtomicLongFieldUpdater<JdbcSqlStat> executeErrorCountUpdater;
final static AtomicLongFieldUpdater<JdbcSqlStat> updateCountUpdater;
final static AtomicLongFieldUpdater<JdbcSqlStat> updateCountMaxUpdater;
final static AtomicLongFieldUpdater<JdbcSqlStat> fetchRowCountUpdater;
final static AtomicLongFieldUpdater<JdbcSqlStat> fetchRowCountMaxUpdater;
final static AtomicLongFieldUpdater<JdbcSqlStat> inTransactionCountUpdater;
final static AtomicLongFieldUpdater<JdbcSqlStat> clobOpenCountUpdater;
final static AtomicLongFieldUpdater<JdbcSqlStat> blobOpenCountUpdater;
final static AtomicLongFieldUpdater<JdbcSqlStat> readStringLengthUpdater;
final static AtomicLongFieldUpdater<JdbcSqlStat> readBytesLengthUpdater;
final static AtomicLongFieldUpdater<JdbcSqlStat> inputStreamOpenCountUpdater;
final static AtomicLongFieldUpdater<JdbcSqlStat> readerOpenCountUpdater;
static {
executeErrorCountUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, "executeErrorCount");
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");
clobOpenCountUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, "clobOpenCount");
blobOpenCountUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, "blobOpenCount");
readStringLengthUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, "readStringLength");
readBytesLengthUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, "readBytesLength");
inputStreamOpenCountUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, "inputStreamOpenCount");
readerOpenCountUpdater = AtomicLongFieldUpdater.newUpdater(JdbcSqlStat.class, "readerOpenCount");
}
private final Histogram histogram = new Histogram(new long[] { //
//
1, 10, 100, 1000, 10 * 1000, //
100 * 1000, 1000 * 1000
//
});
//
});
private final Histogram executeAndResultHoldTimeHistogram = new Histogram(new long[] { //
//
private final Histogram executeAndResultHoldTimeHistogram = new Histogram(new long[] { //
//
1, 10, 100, 1000, 10 * 1000, //
100 * 1000, 1000 * 1000
//
});
//
});
private final Histogram fetchRowCountHistogram = new Histogram(new long[] { //
1, 10, 100, 1000, 10 * 1000 });
private final Histogram fetchRowCountHistogram = new Histogram(new long[] { //
1, 10, 100,
1000, 10 * 1000 });
private final Histogram updateCountHistogram = new Histogram(new long[] { //
1, 10, 100, 1000, 10 * 1000 });
private final Histogram updateCountHistogram = new Histogram(new long[] { //
1, 10, 100,
1000, 10 * 1000 });
public JdbcSqlStat(String sql){
this.sql = sql;
@@ -201,60 +260,60 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean {
public void reset() {
executeLastStartTime = 0;
executeBatchSizeTotal.set(0);
executeBatchSizeMax.set(0);
executeBatchSizeTotalUpdater.set(this, 0);
executeBatchSizeMaxUpdater.set(this, 0);
executeSuccessCount.set(0);
executeSpanNanoTotal.set(0);
executeSpanNanoMax.set(0);
executeSuccessCountUpdater.set(this, 0);
executeSpanNanoTotalUpdater.set(this, 0);
executeSpanNanoMaxUpdater.set(this, 0);
executeNanoSpanMaxOccurTime = 0;
runningCount.set(0);
concurrentMax.set(0);
runningCountUpdater.set(this, 0);
concurrentMaxUpdater.set(this, 0);
executeErrorCount.set(0);
executeErrorCountUpdater.set(this, 0);
executeErrorLast = null;
executeErrorLastTime = 0;
updateCount.set(0);
updateCountMax.set(0);
fetchRowCount.set(0);
fetchRowCountMax.set(0);
updateCountUpdater.set(this, 0);
updateCountMaxUpdater.set(this, 0);
fetchRowCountUpdater.set(this, 0);
fetchRowCountMaxUpdater.set(this, 0);
histogram.reset();
this.lastSlowParameters = null;
inTransactionCount.set(0);
resultSetHoldTimeNano.set(0);
executeAndResultSetHoldTime.set(0);
inTransactionCountUpdater.set(this, 0);
resultSetHoldTimeNanoUpdater.set(this, 0);
executeAndResultSetHoldTimeUpdater.set(this, 0);
fetchRowCountHistogram.reset();
updateCountHistogram.reset();
executeAndResultHoldTimeHistogram.reset();
blobOpenCount.set(0);
clobOpenCount.set(0);
readStringLength.set(0);
readBytesLength.set(0);
inputStreamOpenCount.set(0);
readerOpenCount.set(0);
blobOpenCountUpdater.set(this, 0);
clobOpenCountUpdater.set(this, 0);
readStringLengthUpdater.set(this, 0);
readBytesLengthUpdater.set(this, 0);
inputStreamOpenCountUpdater.set(this, 0);
readerOpenCountUpdater.set(this, 0);
}
public long getConcurrentMax() {
return concurrentMax.get();
return concurrentMax;
}
public long getRunningCount() {
return runningCount.get();
return runningCount;
}
public void addUpdateCount(int delta) {
if (delta > 0) {
this.updateCount.addAndGet(delta);
updateCountUpdater.addAndGet(this, delta);
}
for (;;) {
long max = updateCountMax.get();
long max = updateCountMaxUpdater.get(this);
if (delta <= max) {
break;
}
if (updateCountMax.compareAndSet(max, delta)) {
if (updateCountMaxUpdater.compareAndSet(this, max, delta)) {
break;
}
}
@@ -263,67 +322,67 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean {
}
public long getUpdateCount() {
return updateCount.get();
return updateCount;
}
public long getUpdateCountMax() {
return updateCountMax.get();
return updateCountMax;
}
public long getFetchRowCount() {
return fetchRowCount.get();
return fetchRowCount;
}
public long getFetchRowCountMax() {
return fetchRowCountMax.get();
return fetchRowCountMax;
}
public long getClobOpenCount() {
return clobOpenCount.get();
return clobOpenCount;
}
public void incrementClobOpenCount() {
clobOpenCount.incrementAndGet();
clobOpenCountUpdater.incrementAndGet(this);
}
public long getBlobOpenCount() {
return blobOpenCount.get();
return blobOpenCount;
}
public void incrementBlobOpenCount() {
blobOpenCount.incrementAndGet();
blobOpenCountUpdater.incrementAndGet(this);
}
public long getReadStringLength() {
return readStringLength.get();
return readStringLength;
}
public void addStringReadLength(long length) {
this.readStringLength.addAndGet(length);
readStringLengthUpdater.addAndGet(this, length);
}
public long getReadBytesLength() {
return readBytesLength.get();
return readBytesLength;
}
public void addReadBytesLength(long length) {
this.readBytesLength.addAndGet(length);
readBytesLengthUpdater.addAndGet(this, length);
}
public long getReaderOpenCount() {
return readerOpenCount.get();
return readerOpenCount;
}
public void addReaderOpenCount(int count) {
this.readerOpenCount.addAndGet(count);
readerOpenCountUpdater.addAndGet(this, count);
}
public long getInputStreamOpenCount() {
return inputStreamOpenCount.get();
return inputStreamOpenCount;
}
public void addInputStreamOpenCount(int count) {
this.inputStreamOpenCount.addAndGet(count);
inputStreamOpenCountUpdater.addAndGet(this, count);
}
public long getId() {
@@ -365,13 +424,13 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean {
}
public void addFetchRowCount(long delta) {
this.fetchRowCount.addAndGet(delta);
fetchRowCountUpdater.addAndGet(this, delta);
for (;;) {
long max = fetchRowCountMax.get();
long max = fetchRowCountMaxUpdater.get(this);
if (delta <= max) {
break;
}
if (fetchRowCountMax.compareAndSet(max, delta)) {
if (fetchRowCountMaxUpdater.compareAndSet(this, max, delta)) {
break;
}
}
@@ -380,13 +439,13 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean {
}
public void addExecuteBatchCount(long batchSize) {
executeBatchSizeTotal.addAndGet(batchSize);
executeBatchSizeTotalUpdater.addAndGet(this, batchSize);
// executeBatchSizeMax
for (;;) {
long current = executeBatchSizeMax.get();
long current = executeBatchSizeMaxUpdater.get(this);
if (current < batchSize) {
if (executeBatchSizeMax.compareAndSet(current, batchSize)) {
if (executeBatchSizeMaxUpdater.compareAndSet(this, current, batchSize)) {
break;
} else {
continue;
@@ -398,20 +457,20 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean {
}
public long getExecuteBatchSizeTotal() {
return executeBatchSizeTotal.get();
return executeBatchSizeTotal;
}
public void incrementExecuteSuccessCount() {
executeSuccessCount.incrementAndGet();
executeSuccessCountUpdater.incrementAndGet(this);
}
public void incrementRunningCount() {
long val = runningCount.incrementAndGet();
long val = runningCountUpdater.incrementAndGet(this);
for (;;) {
long max = concurrentMax.get();
long max = concurrentMaxUpdater.get(this);
if (val > max) {
if (concurrentMax.compareAndSet(max, val)) {
if (concurrentMaxUpdater.compareAndSet(this, max, val)) {
break;
} else {
continue;
@@ -423,15 +482,15 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean {
}
public void decrementRunningCount() {
runningCount.decrementAndGet();
runningCountUpdater.decrementAndGet(this);
}
public void decrementExecutingCount() {
runningCount.decrementAndGet();
runningCountUpdater.decrementAndGet(this);
}
public long getExecuteSuccessCount() {
return executeSuccessCount.get();
return executeSuccessCount;
}
public void addExecuteTime(StatementExecuteType executeType, boolean firstResultSet, long nanoSpan) {
@@ -443,12 +502,12 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean {
}
public void addExecuteTime(long nanoSpan) {
executeSpanNanoTotal.addAndGet(nanoSpan);
executeSpanNanoTotalUpdater.addAndGet(this, nanoSpan);
for (;;) {
long current = executeSpanNanoMax.get();
long current = executeSpanNanoMaxUpdater.get(this);
if (current < nanoSpan) {
if (executeSpanNanoMax.compareAndSet(current, nanoSpan)) {
if (executeSpanNanoMaxUpdater.compareAndSet(this, current, nanoSpan)) {
// 可能不准确,但是绝大多数情况下都会正确,性能换取一致性
executeNanoSpanMaxOccurTime = System.currentTimeMillis();
@@ -466,28 +525,28 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean {
}
public long getExecuteMillisTotal() {
return executeSpanNanoTotal.get() / (1000 * 1000);
return executeSpanNanoTotal / (1000 * 1000);
}
public long getExecuteMillisMax() {
return executeSpanNanoMax.get() / (1000 * 1000);
return executeSpanNanoMax / (1000 * 1000);
}
public long getErrorCount() {
return executeErrorCount.get();
return executeErrorCount;
}
@Override
public long getExecuteBatchSizeMax() {
return executeBatchSizeMax.get();
return executeBatchSizeMax;
}
public long getInTransactionCount() {
return inTransactionCount.get();
return inTransactionCount;
}
public void incrementInTransactionCount() {
inTransactionCount.incrementAndGet();
inTransactionCountUpdater.incrementAndGet(this);
}
private static CompositeType COMPOSITE_TYPE = null;
@@ -710,7 +769,7 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean {
}
public void error(Throwable error) {
executeErrorCount.incrementAndGet();
executeErrorCountUpdater.incrementAndGet(this);
executeErrorLastTime = System.currentTimeMillis();
executeErrorLast = error;
@@ -737,20 +796,20 @@ public final class JdbcSqlStat implements JdbcSqlStatMBean {
}
public long getResultSetHoldTimeNano() {
return resultSetHoldTimeNano.get();
return resultSetHoldTimeNano;
}
public long getExecuteAndResultSetHoldTimeNano() {
return executeAndResultSetHoldTime.get();
return executeAndResultSetHoldTime;
}
public void addResultSetHoldTimeNano(long nano) {
resultSetHoldTimeNano.addAndGet(nano);
resultSetHoldTimeNanoUpdater.addAndGet(this, nano);
}
public void addResultSetHoldTimeNano(long statementExecuteNano, long resultHoldTimeNano) {
resultSetHoldTimeNano.addAndGet(resultHoldTimeNano);
executeAndResultSetHoldTime.addAndGet(statementExecuteNano + resultHoldTimeNano);
resultSetHoldTimeNanoUpdater.addAndGet(this, resultHoldTimeNano);
executeAndResultSetHoldTimeUpdater.addAndGet(this, statementExecuteNano + resultHoldTimeNano);
executeAndResultHoldTimeHistogram.record((statementExecuteNano + resultHoldTimeNano) / 1000 / 1000);
updateCountHistogram.record(0);
}
@@ -20,39 +20,63 @@ import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
import com.alibaba.druid.util.Histogram;
public class WebSessionStat {
private final String sessionId;
private final String sessionId;
private final AtomicInteger runningCount = new AtomicInteger();
private final AtomicInteger concurrentMax = new AtomicInteger();
private final AtomicLong requestCount = new AtomicLong(0);
private final AtomicLong requestErrorCount = new AtomicLong(0);
private final AtomicLong requestTimeNano = new AtomicLong();
private volatile int runningCount;
private volatile int concurrentMax;
final static AtomicIntegerFieldUpdater<WebSessionStat> runningCountUpdater = AtomicIntegerFieldUpdater.newUpdater(WebSessionStat.class,
"runningCount");
final static AtomicIntegerFieldUpdater<WebSessionStat> concurrentMaxUpdater = AtomicIntegerFieldUpdater.newUpdater(WebSessionStat.class,
"concurrentMax");
private final AtomicLong jdbcFetchRowCount = new AtomicLong();
private final AtomicLong jdbcUpdateCount = new AtomicLong();
private final AtomicLong jdbcExecuteCount = new AtomicLong();
private final AtomicLong jdbcExecuteTimeNano = new AtomicLong();
private volatile long requestCount;
private volatile long requestErrorCount;
private volatile long requestTimeNano;
private final AtomicLong jdbcCommitCount = new AtomicLong();
private final AtomicLong jdbcRollbackCount = new AtomicLong();
final static AtomicLongFieldUpdater<WebSessionStat> requestCountUpdater = AtomicLongFieldUpdater.newUpdater(WebSessionStat.class,
"requestCount");
final static AtomicLongFieldUpdater<WebSessionStat> requestErrorCountUpdater = AtomicLongFieldUpdater.newUpdater(WebSessionStat.class,
"requestErrorCount");
final static AtomicLongFieldUpdater<WebSessionStat> requestTimeNanoUpdater = AtomicLongFieldUpdater.newUpdater(WebSessionStat.class,
"requestTimeNano");
private long createTimeMillis = -1L;
private volatile long lastAccessTimeMillis = -1L;
private volatile long jdbcFetchRowCount;
private volatile long jdbcUpdateCount;
private volatile long jdbcExecuteCount;
private volatile long jdbcExecuteTimeNano;
final static AtomicLongFieldUpdater<WebSessionStat> jdbcFetchRowCountUpdater = AtomicLongFieldUpdater.newUpdater(WebSessionStat.class,
"jdbcFetchRowCount");
final static AtomicLongFieldUpdater<WebSessionStat> jdbcUpdateCountUpdater = AtomicLongFieldUpdater.newUpdater(WebSessionStat.class,
"jdbcUpdateCount");
final static AtomicLongFieldUpdater<WebSessionStat> jdbcExecuteCountUpdater = AtomicLongFieldUpdater.newUpdater(WebSessionStat.class,
"jdbcExecuteCount");
final static AtomicLongFieldUpdater<WebSessionStat> jdbcExecuteTimeNanoUpdater = AtomicLongFieldUpdater.newUpdater(WebSessionStat.class,
"jdbcExecuteTimeNano");
private Set<String> remoteAddresses = new HashSet<String>();
private volatile long jdbcCommitCount;
private volatile long jdbcRollbackCount;
final static AtomicLongFieldUpdater<WebSessionStat> jdbcCommitCountUpdater = AtomicLongFieldUpdater.newUpdater(WebSessionStat.class,
"jdbcCommitCount");
final static AtomicLongFieldUpdater<WebSessionStat> jdbcRollbackCountUpdater = AtomicLongFieldUpdater.newUpdater(WebSessionStat.class,
"jdbcRollbackCount");
private String principal = null;
private long createTimeMillis = -1L;
private volatile long lastAccessTimeMillis = -1L;
private String userAgent;
private Set<String> remoteAddresses = new HashSet<String>(2);
private Histogram requestIntervalHistogram = Histogram.makeHistogram(8);
private String principal = null;
private String userAgent;
private Histogram requestIntervalHistogram = Histogram.makeHistogram(8);
public WebSessionStat(String sessionId){
super();
@@ -60,17 +84,17 @@ public class WebSessionStat {
}
public void reset() {
concurrentMax.set(0);
requestCount.set(0);
requestErrorCount.set(0);
requestTimeNano.set(0);
concurrentMaxUpdater.set(this, 0);
requestCountUpdater.set(this, 0);
requestErrorCountUpdater.set(this, 0);
requestTimeNanoUpdater.set(this, 0);
jdbcFetchRowCount.set(0);
jdbcUpdateCount.set(0);
jdbcExecuteCount.set(0);
jdbcExecuteTimeNano.set(0);
jdbcCommitCount.set(0);
jdbcRollbackCount.set(0);
jdbcFetchRowCountUpdater.set(this, 0);
jdbcUpdateCountUpdater.set(this, 0);
jdbcExecuteCountUpdater.set(this, 0);
jdbcExecuteTimeNanoUpdater.set(this, 0);
jdbcCommitCountUpdater.set(this, 0);
jdbcRollbackCountUpdater.set(this, 0);
remoteAddresses.clear();
principal = null;
@@ -159,12 +183,12 @@ public class WebSessionStat {
}
public void beforeInvoke() {
int running = runningCount.incrementAndGet();
int running = runningCountUpdater.incrementAndGet(this);
for (;;) {
int max = concurrentMax.get();
int max = concurrentMaxUpdater.get(this);
if (running > max) {
if (concurrentMax.compareAndSet(max, running)) {
if (concurrentMaxUpdater.compareAndSet(this, max, running)) {
break;
} else {
continue;
@@ -183,16 +207,16 @@ public class WebSessionStat {
}
public void incrementRequestCount() {
requestCount.incrementAndGet();
requestCountUpdater.incrementAndGet(this);
}
public void afterInvoke(Throwable error, long nanos) {
runningCount.decrementAndGet();
runningCountUpdater.decrementAndGet(this);
reacord(nanos);
}
public void reacord(long nanos) {
requestTimeNano.addAndGet(nanos);
requestTimeNanoUpdater.addAndGet(this, nanos);
WebRequestStat requestStat = WebRequestStat.current();
if (requestStat != null) {
@@ -210,23 +234,23 @@ public class WebSessionStat {
}
public int getRunningCount() {
return this.runningCount.get();
return this.runningCount;
}
public long getConcurrentMax() {
return concurrentMax.get();
return concurrentMax;
}
public long getRequestCount() {
return requestCount.get();
return requestCount;
}
public long getRequestErrorCount() {
return requestErrorCount.get();
return requestErrorCount;
}
public long getRequestTimeNano() {
return requestTimeNano.get();
return requestTimeNano;
}
public long getRequestTimeMillis() {
@@ -234,31 +258,31 @@ public class WebSessionStat {
}
public void addJdbcFetchRowCount(long delta) {
this.jdbcFetchRowCount.addAndGet(delta);
jdbcFetchRowCountUpdater.addAndGet(this, delta);
}
public long getJdbcFetchRowCount() {
return jdbcFetchRowCount.get();
return jdbcFetchRowCount;
}
public void addJdbcUpdateCount(long updateCount) {
this.jdbcUpdateCount.addAndGet(updateCount);
jdbcUpdateCountUpdater.addAndGet(this, updateCount);
}
public long getJdbcUpdateCount() {
return jdbcUpdateCount.get();
return jdbcUpdateCount;
}
public void incrementJdbcExecuteCount() {
jdbcExecuteCount.incrementAndGet();
jdbcExecuteCountUpdater.incrementAndGet(this);
}
public void addJdbcExecuteCount(long executeCount) {
jdbcExecuteCount.addAndGet(executeCount);
jdbcExecuteCountUpdater.addAndGet(this, executeCount);
}
public long getJdbcExecuteCount() {
return jdbcExecuteCount.get();
return jdbcExecuteCount;
}
public long getJdbcExecuteTimeMillis() {
@@ -266,35 +290,35 @@ public class WebSessionStat {
}
public long getJdbcExecuteTimeNano() {
return jdbcExecuteTimeNano.get();
return jdbcExecuteTimeNano;
}
public void addJdbcExecuteTimeNano(long nano) {
jdbcExecuteTimeNano.addAndGet(nano);
jdbcExecuteTimeNanoUpdater.addAndGet(this, nano);
}
public void incrementJdbcCommitCount() {
jdbcCommitCount.incrementAndGet();
jdbcCommitCountUpdater.incrementAndGet(this);
}
public long getJdbcCommitCount() {
return jdbcCommitCount.get();
return jdbcCommitCount;
}
public void addJdbcCommitCount(long commitCount) {
this.jdbcCommitCount.addAndGet(commitCount);
jdbcCommitCountUpdater.addAndGet(this, commitCount);
}
public void incrementJdbcRollbackCount() {
jdbcRollbackCount.incrementAndGet();
jdbcRollbackCountUpdater.incrementAndGet(this);
}
public long getJdbcRollbackCount() {
return jdbcRollbackCount.get();
return jdbcRollbackCount;
}
public void addJdbcRollbackCount(long rollbackCount) {
this.jdbcRollbackCount.addAndGet(rollbackCount);
jdbcRollbackCountUpdater.addAndGet(this, rollbackCount);
}
public long[] getRequestInterval() {
@@ -18,48 +18,93 @@ package com.alibaba.druid.support.http.stat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import com.alibaba.druid.support.profile.ProfileStat;
import com.alibaba.druid.support.profile.Profiler;
public class WebURIStat {
private final String uri;
private final String uri;
private final AtomicInteger runningCount = new AtomicInteger();
private final AtomicInteger concurrentMax = new AtomicInteger();
private final AtomicLong requestCount = new AtomicLong(0);
private final AtomicLong requestTimeNano = new AtomicLong();
private volatile int runningCount;
private volatile int concurrentMax;
private volatile long requestCount;
private volatile long requestTimeNano;
final static AtomicIntegerFieldUpdater<WebURIStat> runningCountUpdater = AtomicIntegerFieldUpdater.newUpdater(WebURIStat.class,
"runningCount");
final static AtomicIntegerFieldUpdater<WebURIStat> concurrentMaxUpdater = AtomicIntegerFieldUpdater.newUpdater(WebURIStat.class,
"concurrentMax");
final static AtomicLongFieldUpdater<WebURIStat> requestCountUpdater = AtomicLongFieldUpdater.newUpdater(WebURIStat.class,
"requestCount");
final static AtomicLongFieldUpdater<WebURIStat> requestTimeNanoUpdater = AtomicLongFieldUpdater.newUpdater(WebURIStat.class,
"requestTimeNano");
private final AtomicLong jdbcFetchRowCount = new AtomicLong();
private final AtomicLong jdbcFetchRowPeak = new AtomicLong(); // 单次请求读取行数的峰值
private volatile long jdbcFetchRowCount;
private volatile long jdbcFetchRowPeak; // 单次请求读取行数的峰值
final static AtomicLongFieldUpdater<WebURIStat> jdbcFetchRowCountUpdater = AtomicLongFieldUpdater.newUpdater(WebURIStat.class,
"jdbcFetchRowCount");
final static AtomicLongFieldUpdater<WebURIStat> jdbcFetchRowPeakUpdater = AtomicLongFieldUpdater.newUpdater(WebURIStat.class,
"jdbcFetchRowPeak");
private final AtomicLong jdbcUpdateCount = new AtomicLong();
private final AtomicLong jdbcUpdatePeak = new AtomicLong(); // 单次请求更新行数的峰值
private volatile long jdbcUpdateCount;
private volatile long jdbcUpdatePeak; // 单次请求更新行数的峰值
final static AtomicLongFieldUpdater<WebURIStat> jdbcUpdateCountUpdater = AtomicLongFieldUpdater.newUpdater(WebURIStat.class,
"jdbcUpdateCount");
final static AtomicLongFieldUpdater<WebURIStat> jdbcUpdatePeakUpdater = AtomicLongFieldUpdater.newUpdater(WebURIStat.class,
"jdbcUpdatePeak");
private final AtomicLong jdbcExecuteCount = new AtomicLong();
private final AtomicLong jdbcExecuteErrorCount = new AtomicLong();
private final AtomicLong jdbcExecutePeak = new AtomicLong(); // 单次请求执行SQL次数的峰值
private final AtomicLong jdbcExecuteTimeNano = new AtomicLong();
private volatile long jdbcExecuteCount;
private volatile long jdbcExecuteErrorCount;
private volatile long jdbcExecutePeak; // 单次请求执行SQL次数的峰值
private volatile long jdbcExecuteTimeNano;
final static AtomicLongFieldUpdater<WebURIStat> jdbcExecuteCountUpdater = AtomicLongFieldUpdater.newUpdater(WebURIStat.class,
"jdbcExecuteCount");
final static AtomicLongFieldUpdater<WebURIStat> jdbcExecuteErrorCountUpdater = AtomicLongFieldUpdater.newUpdater(WebURIStat.class,
"jdbcExecuteErrorCount");
final static AtomicLongFieldUpdater<WebURIStat> jdbcExecutePeakUpdater = AtomicLongFieldUpdater.newUpdater(WebURIStat.class,
"jdbcExecutePeak");
final static AtomicLongFieldUpdater<WebURIStat> jdbcExecuteTimeNanoUpdater = AtomicLongFieldUpdater.newUpdater(WebURIStat.class,
"jdbcExecuteTimeNano");
private final AtomicLong jdbcCommitCount = new AtomicLong();
private final AtomicLong jdbcRollbackCount = new AtomicLong();
private volatile long jdbcCommitCount;
private volatile long jdbcRollbackCount;
final static AtomicLongFieldUpdater<WebURIStat> jdbcCommitCountUpdater = AtomicLongFieldUpdater.newUpdater(WebURIStat.class,
"jdbcCommitCount");
final static AtomicLongFieldUpdater<WebURIStat> jdbcRollbackCountUpdater = AtomicLongFieldUpdater.newUpdater(WebURIStat.class,
"jdbcRollbackCount");
private final AtomicLong jdbcPoolConnectionOpenCount = new AtomicLong();
private final AtomicLong jdbcPoolConnectionCloseCount = new AtomicLong();
private volatile long jdbcPoolConnectionOpenCount;
private volatile long jdbcPoolConnectionCloseCount;
final static AtomicLongFieldUpdater<WebURIStat> jdbcPoolConnectionOpenCountUpdater = AtomicLongFieldUpdater.newUpdater(WebURIStat.class,
"jdbcPoolConnectionOpenCount");
final static AtomicLongFieldUpdater<WebURIStat> jdbcPoolConnectionCloseCountUpdater = AtomicLongFieldUpdater.newUpdater(WebURIStat.class,
"jdbcPoolConnectionCloseCount");
private final AtomicLong jdbcResultSetOpenCount = new AtomicLong();
private final AtomicLong jdbcResultSetCloseCount = new AtomicLong();
private volatile long jdbcResultSetOpenCount;
private volatile long jdbcResultSetCloseCount;
private final AtomicLong errorCount = new AtomicLong();
private volatile long errorCount;
private volatile long lastAccessTimeMillis = -1L;
private volatile long lastAccessTimeMillis = -1L;
private ProfileStat profiletat = new ProfileStat();
private volatile ProfileStat profiletat;
private final static ThreadLocal<WebURIStat> currentLocal = new ThreadLocal<WebURIStat>();
final static AtomicLongFieldUpdater<WebURIStat> jdbcResultSetOpenCountUpdater = AtomicLongFieldUpdater.newUpdater(WebURIStat.class,
"jdbcResultSetOpenCount");
final static AtomicLongFieldUpdater<WebURIStat> jdbcResultSetCloseCountUpdater = AtomicLongFieldUpdater.newUpdater(WebURIStat.class,
"jdbcResultSetCloseCount");
final static AtomicLongFieldUpdater<WebURIStat> errorCountUpdater = AtomicLongFieldUpdater.newUpdater(WebURIStat.class,
"errorCount");
final static AtomicReferenceFieldUpdater<WebURIStat, ProfileStat> profiletatUpdater;
static {
profiletatUpdater = AtomicReferenceFieldUpdater.newUpdater(WebURIStat.class, ProfileStat.class, "profiletat");
}
private final static ThreadLocal<WebURIStat> currentLocal = new ThreadLocal<WebURIStat>();
public WebURIStat(String uri){
super();
@@ -77,12 +122,12 @@ public class WebURIStat {
public void beforeInvoke() {
currentLocal.set(this);
int running = runningCount.incrementAndGet();
int running = runningCountUpdater.incrementAndGet(this);
for (;;) {
int max = concurrentMax.get();
int max = concurrentMaxUpdater.get(this);
if (running > max) {
if (concurrentMax.compareAndSet(max, running)) {
if (concurrentMaxUpdater.compareAndSet(this, max, running)) {
break;
} else {
continue;
@@ -92,7 +137,7 @@ public class WebURIStat {
}
}
requestCount.incrementAndGet();
requestCountUpdater.incrementAndGet(this);
WebRequestStat requestStat = WebRequestStat.current();
if (requestStat != null) {
@@ -103,11 +148,11 @@ public class WebURIStat {
}
public void afterInvoke(Throwable error, long nanos) {
runningCount.decrementAndGet();
requestTimeNano.addAndGet(nanos);
runningCountUpdater.decrementAndGet(this);
requestTimeNanoUpdater.addAndGet(this, nanos);
if (error != null) {
errorCount.incrementAndGet();
errorCountUpdater.incrementAndGet(this);
}
{
@@ -118,12 +163,12 @@ public class WebURIStat {
this.addJdbcFetchRowCount(fetchRowCount);
for (;;) {
long peak = jdbcFetchRowPeak.get();
long peak = jdbcFetchRowPeakUpdater.get(this);
if (fetchRowCount <= peak) {
break;
}
if (jdbcFetchRowPeak.compareAndSet(peak, fetchRowCount)) {
if (jdbcFetchRowPeakUpdater.compareAndSet(this, peak, fetchRowCount)) {
break;
}
}
@@ -133,12 +178,12 @@ public class WebURIStat {
this.addJdbcExecuteCount(executeCount);
for (;;) {
long peak = jdbcExecutePeak.get();
long peak = jdbcExecutePeakUpdater.get(this);
if (executeCount <= peak) {
break;
}
if (jdbcExecutePeak.compareAndSet(peak, executeCount)) {
if (jdbcExecutePeakUpdater.compareAndSet(this, peak, executeCount)) {
break;
}
}
@@ -148,19 +193,19 @@ public class WebURIStat {
this.addJdbcUpdateCount(updateCount);
for (;;) {
long peak = jdbcUpdatePeak.get();
long peak = jdbcUpdatePeakUpdater.get(this);
if (updateCount <= peak) {
break;
}
if (jdbcUpdatePeak.compareAndSet(peak, updateCount)) {
if (jdbcUpdatePeakUpdater.compareAndSet(this, peak, updateCount)) {
break;
}
}
}
this.jdbcExecuteErrorCount.addAndGet(localStat.getJdbcExecuteErrorCount());
this.jdbcExecuteTimeNano.addAndGet(localStat.getJdbcExecuteTimeNano());
jdbcExecuteErrorCountUpdater.addAndGet(this, localStat.getJdbcExecuteErrorCount());
jdbcExecuteTimeNanoUpdater.addAndGet(this, localStat.getJdbcExecuteTimeNano());
this.addJdbcPoolConnectionOpenCount(localStat.getJdbcPoolConnectionOpenCount());
this.addJdbcPoolConnectionCloseCount(localStat.getJdbcPoolConnectionCloseCount());
@@ -176,19 +221,19 @@ public class WebURIStat {
}
public int getRunningCount() {
return this.runningCount.get();
return this.runningCount;
}
public long getConcurrentMax() {
return concurrentMax.get();
return concurrentMax;
}
public long getRequestCount() {
return requestCount.get();
return requestCount;
}
public long getRequestTimeNano() {
return requestTimeNano.get();
return requestTimeNano;
}
public long getRequestTimeMillis() {
@@ -196,47 +241,47 @@ public class WebURIStat {
}
public void addJdbcFetchRowCount(long delta) {
this.jdbcFetchRowCount.addAndGet(delta);
jdbcFetchRowCountUpdater.addAndGet(this, delta);
}
public long getJdbcFetchRowCount() {
return jdbcFetchRowCount.get();
return jdbcFetchRowCount;
}
public long getJdbcFetchRowPeak() {
return jdbcFetchRowPeak.get();
return jdbcFetchRowPeak;
}
public void addJdbcUpdateCount(long updateCount) {
this.jdbcUpdateCount.addAndGet(updateCount);
jdbcUpdateCountUpdater.addAndGet(this, updateCount);
}
public long getJdbcUpdateCount() {
return jdbcUpdateCount.get();
return jdbcUpdateCount;
}
public long getJdbcUpdatePeak() {
return jdbcUpdatePeak.get();
return jdbcUpdatePeak;
}
public void incrementJdbcExecuteCount() {
jdbcExecuteCount.incrementAndGet();
jdbcExecuteCountUpdater.incrementAndGet(this);
}
public void addJdbcExecuteCount(long executeCount) {
jdbcExecuteCount.addAndGet(executeCount);
jdbcExecuteCountUpdater.addAndGet(this, executeCount);
}
public long getJdbcExecuteCount() {
return jdbcExecuteCount.get();
return jdbcExecuteCount;
}
public AtomicLong getJdbcExecuteErrorCount() {
public long getJdbcExecuteErrorCount() {
return jdbcExecuteErrorCount;
}
public long getJdbcExecutePeak() {
return jdbcExecutePeak.get();
return jdbcExecutePeak;
}
public long getJdbcExecuteTimeMillis() {
@@ -244,23 +289,23 @@ public class WebURIStat {
}
public long getJdbcExecuteTimeNano() {
return jdbcExecuteTimeNano.get();
return jdbcExecuteTimeNano;
}
public void incrementJdbcCommitCount() {
jdbcCommitCount.incrementAndGet();
jdbcCommitCountUpdater.incrementAndGet(this);
}
public long getJdbcCommitCount() {
return jdbcCommitCount.get();
return jdbcCommitCount;
}
public void incrementJdbcRollbackCount() {
jdbcRollbackCount.incrementAndGet();
jdbcRollbackCountUpdater.incrementAndGet(this);
}
public long getJdbcRollbackCount() {
return jdbcRollbackCount.get();
return jdbcRollbackCount;
}
public void setLastAccessTimeMillis(long lastAccessTimeMillis) {
@@ -280,50 +325,56 @@ public class WebURIStat {
}
public long getErrorCount() {
return errorCount.get();
return errorCount;
}
public long getJdbcPoolConnectionOpenCount() {
return jdbcPoolConnectionOpenCount.get();
return jdbcPoolConnectionOpenCount;
}
public void addJdbcPoolConnectionOpenCount(long delta) {
jdbcPoolConnectionOpenCount.addAndGet(delta);
jdbcPoolConnectionOpenCountUpdater.addAndGet(this, delta);
}
public void incrementJdbcPoolConnectionOpenCount() {
jdbcPoolConnectionOpenCount.incrementAndGet();
jdbcPoolConnectionOpenCountUpdater.incrementAndGet(this);
}
public long getJdbcPoolConnectionCloseCount() {
return jdbcPoolConnectionCloseCount.get();
return jdbcPoolConnectionCloseCount;
}
public void addJdbcPoolConnectionCloseCount(long delta) {
jdbcPoolConnectionCloseCount.addAndGet(delta);
jdbcPoolConnectionCloseCountUpdater.addAndGet(this, delta);
}
public void incrementJdbcPoolConnectionCloseCount() {
jdbcPoolConnectionCloseCount.incrementAndGet();
jdbcPoolConnectionCloseCountUpdater.incrementAndGet(this);
}
public long getJdbcResultSetOpenCount() {
return jdbcResultSetOpenCount.get();
return jdbcResultSetOpenCount;
}
public void addJdbcResultSetOpenCount(long delta) {
jdbcResultSetOpenCount.addAndGet(delta);
jdbcResultSetOpenCountUpdater.addAndGet(this, delta);
}
public long getJdbcResultSetCloseCount() {
return jdbcResultSetCloseCount.get();
return jdbcResultSetCloseCount;
}
public void addJdbcResultSetCloseCount(long delta) {
jdbcResultSetCloseCount.addAndGet(delta);
jdbcResultSetCloseCountUpdater.addAndGet(this, delta);
}
public ProfileStat getProfiletat() {
if (profiletat != null) {
return profiletat;
}
profiletatUpdater.compareAndSet(this, null, new ProfileStat());
return profiletat;
}
@@ -3,8 +3,6 @@ package com.alibaba.druid.stat;
import java.lang.management.ManagementFactory;
import java.text.NumberFormat;
import com.alibaba.druid.util.Histogram;
import junit.framework.TestCase;
public class HistogramMemoryTest extends TestCase {
@@ -15,8 +13,8 @@ public class HistogramMemoryTest extends TestCase {
final int COUNT = 1024 * 1;
Object[] items = new Object[COUNT];
for (int i = 0; i < COUNT; ++i) {
// items[i] = new JdbcSqlStat("");
items[i] = Histogram.makeHistogram(20);
items[i] = new JdbcSqlStat("");
// items[i] = Histogram.makeHistogram(20);
}
long memoryEnd = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed();