com.aliyun.openservices.ons.api.exactlyonce.manager.impl.MetricServiceImpl Maven / Gradle / Ivy
package com.aliyun.openservices.ons.api.exactlyonce.manager.impl;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import com.aliyun.openservices.shade.com.alibaba.rocketmq.common.utils.ThreadUtils;
import com.aliyun.openservices.shade.com.alibaba.rocketmq.logging.InternalLogger;
import com.aliyun.openservices.ons.api.exactlyonce.TxConstant;
import com.aliyun.openservices.ons.api.exactlyonce.aop.model.MQTxContext;
import com.aliyun.openservices.ons.api.exactlyonce.manager.util.LogUtil;
import com.aliyun.openservices.ons.api.exactlyonce.manager.util.MetricsUtil;
import com.aliyun.openservices.ons.api.exactlyonce.manager.util.TxContextUtil;
import com.aliyun.openservices.ons.api.impl.util.ClientLoggerUtil;
/**
* @author gongshi
*/
public class MetricServiceImpl {
private static final InternalLogger LOGGER = ClientLoggerUtil.getClientLogger();
private volatile int commitQps;
private volatile int rollbackQps;
private volatile long averageProcessTime;
private volatile long averagePersistenceTime;
private volatile long averageConsumeTime;
private volatile AtomicInteger commitTotal = new AtomicInteger(0);
private volatile AtomicInteger rollbackTotal = new AtomicInteger(0);
private volatile AtomicLong processTimeTotal = new AtomicLong(0);
private volatile AtomicLong persistenceTimeTotal = new AtomicLong(0);
private volatile AtomicLong consumeTimeTotal = new AtomicLong(0);
private volatile AtomicLong forbidDupTimes = new AtomicLong(0);
private volatile int queryAckedPre;
private volatile int queryExpiredPre;
private volatile int queryMsgIdCountPre;
private volatile int insertRecordPre;
private volatile int deleteRecordPre;
private volatile int dbReadPre;
private volatile int dbWritePre;
private volatile long queryAckedRt;
private volatile long queryExpiredRt;
private volatile long queryMsgIdCountRt;
private volatile long insertRecordRt;
private volatile long deleteRecordRt;
private volatile AtomicLong queryAckedTimeUsed = new AtomicLong(0);
private volatile AtomicLong queryExpiredTimeUsed = new AtomicLong(0);
private volatile AtomicLong queryMsgIdCountTimeUsed = new AtomicLong(0);
private volatile AtomicLong insertRecordTimeUsed = new AtomicLong(0);
private volatile AtomicLong deleteRecordTimeUsed = new AtomicLong(0);
private volatile AtomicInteger queryAckedTimes = new AtomicInteger(0);
private volatile AtomicInteger queryExpiredTimes = new AtomicInteger(0);
private volatile AtomicInteger queryMsgIdCountTimes = new AtomicInteger(0);
private volatile AtomicInteger insertRecordTimes = new AtomicInteger(0);
private volatile AtomicInteger deleteRecordTimes = new AtomicInteger(0);
private volatile AtomicInteger dbRead = new AtomicInteger(0);
private volatile AtomicInteger dbWrite = new AtomicInteger(0);
private ScheduledThreadPoolExecutor refreshExecuter = new ScheduledThreadPoolExecutor(1,
ThreadUtils.newThreadFactory("ExactlyOnceConsumer", false));
public void record(MQTxContext context) {
if (context == null) {
return;
}
record(context.getMessageId(), MetricsUtil.getProcessTime(context), MetricsUtil.getPersistenceTime(context),
MetricsUtil.getConsumeTime(context), System.currentTimeMillis(), TxContextUtil.isTxContextCommitted(context), context.isDup());
}
public void record(String messageId, long processTime, long persistenceTime, long consumeTime,
long timestamp, boolean isCommit, boolean isDup) {
this.processTimeTotal.addAndGet(processTime);
this.persistenceTimeTotal.addAndGet(persistenceTime);
this.consumeTimeTotal.addAndGet(consumeTime);
if (isDup) {
this.forbidDupTimes.incrementAndGet();
}
if (isCommit) {
this.commitTotal.incrementAndGet();
} else {
this.rollbackTotal.incrementAndGet();
}
LogUtil.debug(LOGGER, "record consume status, msgId:{}, processTime:{}, persistenceTime:{}, consumeTime:{} recordTimestamp:{}, commit:{}, dup:{}",
messageId, processTime, persistenceTime, consumeTime, timestamp, isCommit, isDup);
}
public void computeTxStatsData() {
try {
int consumeCount = this.commitTotal.get() + this.rollbackTotal.get();
this.commitQps = this.commitTotal.getAndSet(0) / TxConstant.CONSUME_STATUS_STATISTICS_INTERVAL_SECOND;
this.rollbackQps = this.rollbackTotal.getAndSet(0) / TxConstant.CONSUME_STATUS_STATISTICS_INTERVAL_SECOND;
this.averageProcessTime = consumeCount == 0 ? 0 : this.processTimeTotal.getAndSet(0) / consumeCount;
this.averagePersistenceTime = consumeCount == 0 ? 0 : this.persistenceTimeTotal.getAndSet(0) / consumeCount;
this.averageConsumeTime = consumeCount == 0 ? 0 : this.consumeTimeTotal.getAndSet(0) / consumeCount;
this.queryAckedPre = this.queryAckedTimes.getAndSet(0);
this.queryExpiredPre = this.queryExpiredTimes.getAndSet(0);
this.queryMsgIdCountPre = this.queryMsgIdCountTimes.getAndSet(0);
this.insertRecordPre = this.insertRecordTimes.getAndSet(0);
this.deleteRecordPre = this.deleteRecordTimes.getAndSet(0);
this.dbReadPre = this.dbRead.getAndSet(0);
this.dbWritePre = this.dbWrite.getAndSet(0);
this.queryAckedRt = this.queryAckedPre == 0 ? 0 : this.queryAckedTimeUsed.getAndSet(0) / this.queryAckedPre;
this.queryExpiredRt = this.queryExpiredPre == 0 ? 0 : this.queryExpiredTimeUsed.getAndSet(0) / this.queryExpiredPre;
this.queryMsgIdCountRt = this.queryMsgIdCountPre == 0 ? 0 : this.queryMsgIdCountTimeUsed.getAndSet(0) / this.queryMsgIdCountPre;
this.insertRecordRt = this.insertRecordPre == 0 ? 0 : this.insertRecordTimeUsed.getAndSet(0) / this.insertRecordPre;
this.deleteRecordRt = this.deleteRecordPre == 0 ? 0 : this.deleteRecordTimeUsed.getAndSet(0) / this.deleteRecordPre;
LogUtil.info(LOGGER, "Metrics forbidDupCount:{}, commitQps:{}, rollbackQps:{}, averageProcessTime:{}ms, averagePersistenceTime:{}ms, averageConsumeTime:{}ms"
+ " queryAcked:{}/min, queryExpired:{}/min, queryMsgCount:{}/min, insertRecord:{}/min, deleteRecord:{}/min, dbRead:{}/min, dbWrite:{}/min"
+ " queryAckedRt:{}ms, queryExpiredRt:{}ms, queryMsgCountRt:{}ms, insertRecordRt:{}ms, deleteRecordRt:{}ms",
this.forbidDupTimes, this.commitQps, this.rollbackQps, this.averageProcessTime, this.averagePersistenceTime, this.averageConsumeTime,
this.queryAckedPre, this.queryExpiredPre, this.queryMsgIdCountPre, this.insertRecordPre, this.deleteRecordPre, this.dbReadPre, this.dbWritePre,
this.queryAckedRt, this.queryExpiredRt, this.queryMsgIdCountRt, this.insertRecordRt, this.deleteRecordRt);
} catch (Throwable e) {
LogUtil.error(LOGGER, "computeTxStats fail:{}", e.getMessage());
}
}
public Map getCurrentConsumeStatus() {
Map statusMap = new HashMap(13);
statusMap.put(TxConstant.COMMITQPS_KEY, String.valueOf(commitQps));
statusMap.put(TxConstant.ROLLBACKQPS_KEY, String.valueOf(rollbackQps));
statusMap.put(TxConstant.AVERAGECONSUMETIME_KEY, String.valueOf(averageConsumeTime));
statusMap.put(TxConstant.AVERAGEPROCESSTIME_KEY, String.valueOf(averageProcessTime));
statusMap.put(TxConstant.AVERAGEPERSISTENCETIME_KEY, String.valueOf(averagePersistenceTime));
statusMap.put(TxConstant.TOTALFORBIDDUPLICATION_KEY, String.valueOf(forbidDupTimes.get()));
statusMap.put(TxConstant.DB_QUERYACKED_KEY, String.valueOf(queryAckedPre));
statusMap.put(TxConstant.DB_QUERYEXPIRED_KEY, String.valueOf(queryExpiredPre));
statusMap.put(TxConstant.DB_QUERYMSGIDCOUNT_KEY, String.valueOf(queryMsgIdCountPre));
statusMap.put(TxConstant.DB_INSERTRECORD_KEY, String.valueOf(insertRecordPre));
statusMap.put(TxConstant.DB_DELETERECORD_KEY, String.valueOf(deleteRecordPre));
statusMap.put(TxConstant.DB_READ_KEY, String.valueOf(dbReadPre));
statusMap.put(TxConstant.DB_WRITE_KEY, String.valueOf(dbWrite));
statusMap.put(TxConstant.DB_QUERYACKED_RT_KEY, String.valueOf(queryAckedRt));
statusMap.put(TxConstant.DB_QUERYEXPIRED_RT_KEY, String.valueOf(queryExpiredRt));
statusMap.put(TxConstant.DB_QUERYMSGIDCOUNT_RT_KEY, String.valueOf(queryMsgIdCountRt));
statusMap.put(TxConstant.DB_INSERTRECORD_RT_KEY, String.valueOf(insertRecordRt));
statusMap.put(TxConstant.DB_DELETERECORD_RT_KEY, String.valueOf(deleteRecordRt));
return statusMap;
}
public void incQueryExpired(long begin) {
this.queryExpiredTimes.incrementAndGet();
this.dbRead.incrementAndGet();
this.queryExpiredTimeUsed.addAndGet(System.currentTimeMillis() - begin);
}
public void incQueryAcked(long begin) {
this.queryAckedTimes.incrementAndGet();
this.dbRead.incrementAndGet();
this.queryAckedTimeUsed.addAndGet(System.currentTimeMillis() - begin);
}
public void incQueryMsgIdCount(long begin) {
this.queryMsgIdCountTimes.incrementAndGet();
this.dbRead.incrementAndGet();
this.queryMsgIdCountTimeUsed.addAndGet(System.currentTimeMillis() - begin);
}
public void incInsertRecord(long begin) {
this.insertRecordTimes.incrementAndGet();
this.dbWrite.incrementAndGet();
this.insertRecordTimeUsed.addAndGet(System.currentTimeMillis() - begin);
}
public void incDeleteRecord(long begin) {
this.deleteRecordTimes.incrementAndGet();
this.dbWrite.incrementAndGet();
this.deleteRecordTimeUsed.addAndGet(System.currentTimeMillis() - begin);
}
public void incRead() {
this.dbRead.incrementAndGet();
}
public void incWrite() {
this.dbWrite.incrementAndGet();
}
public void start() {
refreshExecuter.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
computeTxStatsData();
}
}, TxConstant.CONSUME_STATUS_STATISTICS_INTERVAL_SECOND, TxConstant.CONSUME_STATUS_STATISTICS_INTERVAL_SECOND, TimeUnit.SECONDS);
}
public void stop() {
ThreadUtils.shutdownGracefully(refreshExecuter, 10000, TimeUnit.MILLISECONDS);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy