All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.alibaba.rocketmq.common.protocol.body.ConsumerRunningInfo Maven / Gradle / Ivy
package com.alibaba.rocketmq.common.protocol.body;
import com.alibaba.rocketmq.common.message.MessageQueue;
import com.alibaba.rocketmq.common.protocol.heartbeat.ConsumeType;
import com.alibaba.rocketmq.common.protocol.heartbeat.SubscriptionData;
import com.alibaba.rocketmq.remoting.protocol.RemotingSerializable;
import java.util.*;
import java.util.Map.Entry;
/**
* Consumer内部数据结构
*/
public class ConsumerRunningInfo extends RemotingSerializable {
public static final String PROP_NAMESERVER_ADDR = "PROP_NAMESERVER_ADDR";
public static final String PROP_THREADPOOL_CORE_SIZE = "PROP_THREADPOOL_CORE_SIZE";
public static final String PROP_CONSUME_ORDERLY = "PROP_CONSUMEORDERLY";
public static final String PROP_CONSUME_TYPE = "PROP_CONSUME_TYPE";
public static final String PROP_CLIENT_VERSION = "PROP_CLIENT_VERSION";
public static final String PROP_CONSUMER_START_TIMESTAMP = "PROP_CONSUMER_START_TIMESTAMP";
// 各种配置及运行数据
private Properties properties = new Properties();
// 订阅关系
private TreeSet subscriptionSet = new TreeSet();
// 消费进度、Rebalance、内部消费队列的信息
private TreeMap mqTable = new TreeMap();
// RT、TPS统计
private TreeMap statusTable = new TreeMap();
// jstack的结果
private String jstack;
private Map stackTraceElementMap;
/**
* 分析订阅关系是否相同
*/
public static boolean analyzeSubscription(final TreeMap criTable) {
ConsumerRunningInfo prev = criTable.firstEntry().getValue();
boolean push = false;
{
String property = prev.getProperties().getProperty(ConsumerRunningInfo.PROP_CONSUME_TYPE);
// todo: 兼容旧版本客户端
if (property == null) {
property = ((ConsumeType) prev.getProperties().get(ConsumerRunningInfo.PROP_CONSUME_TYPE)).name();
}
push = ConsumeType.valueOf(property) == ConsumeType.CONSUME_PASSIVELY;
}
boolean startForAWhile = false;
{
// todo: 兼容旧版本客户端
String property = prev.getProperties().getProperty(ConsumerRunningInfo.PROP_CONSUMER_START_TIMESTAMP);
if (property == null) {
property = String.valueOf(prev.getProperties().get(ConsumerRunningInfo.PROP_CONSUMER_START_TIMESTAMP));
}
startForAWhile = (System.currentTimeMillis() - Long.parseLong(property)) > (1000 * 60 * 2);
}
// 只检测PUSH
if (push && startForAWhile) {
// 分析订阅关系是否相同
{
Iterator> it = criTable.entrySet().iterator();
while (it.hasNext()) {
Entry next = it.next();
ConsumerRunningInfo current = next.getValue();
boolean equals = current.getSubscriptionSet().equals(prev.getSubscriptionSet());
// 发现订阅关系有误
if (!equals) {
// Different subscription in the same group of consumer
return false;
}
prev = next.getValue();
}
if (prev != null) {
// 无订阅关系
if (prev.getSubscriptionSet().isEmpty()) {
// Subscription empty!
return false;
}
}
}
}
return true;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public TreeSet getSubscriptionSet() {
return subscriptionSet;
}
public void setSubscriptionSet(TreeSet subscriptionSet) {
this.subscriptionSet = subscriptionSet;
}
public static boolean analyzeRebalance(final TreeMap criTable) {
return true;
}
public static String analyzeProcessQueue(final String clientId, ConsumerRunningInfo info) {
StringBuilder sb = new StringBuilder();
boolean push = false;
{
String property = info.getProperties().getProperty(ConsumerRunningInfo.PROP_CONSUME_TYPE);
// todo: 兼容旧版本客户端
if (property == null) {
property = ((ConsumeType) info.getProperties().get(ConsumerRunningInfo.PROP_CONSUME_TYPE)).name();
}
push = ConsumeType.valueOf(property) == ConsumeType.CONSUME_PASSIVELY;
}
boolean orderMsg = false;
{
String property = info.getProperties().getProperty(ConsumerRunningInfo.PROP_CONSUME_ORDERLY);
orderMsg = Boolean.parseBoolean(property);
}
if (push) {
Iterator> it = info.getMqTable().entrySet().iterator();
while (it.hasNext()) {
Entry next = it.next();
MessageQueue mq = next.getKey();
ProcessQueueInfo pq = next.getValue();
// 顺序消息
if (orderMsg) {
// 没锁住
if (!pq.isLocked()) {
sb.append(String.format("%s %s can't lock for a while, %dms\n", //
clientId, //
mq, //
System.currentTimeMillis() - pq.getLastLockTimestamp()));
}
// 锁住
else {
// Rebalance已经丢弃此队列,但是没有正常释放Lock
if (pq.isDroped() && (pq.getTryUnlockTimes() > 0)) {
sb.append(String.format("%s %s unlock %d times, still failed\n", //
clientId, //
mq, //
pq.getTryUnlockTimes()));
}
}
// 事务消息未提交
}
// 乱序消息
else {
long diff = System.currentTimeMillis() - pq.getLastConsumeTimestamp();
// 在有消息的情况下,超过1分钟没再消费消息了
if (diff > (1000 * 60) && pq.getCachedMsgCount() > 0) {
sb.append(String.format("%s %s can't consume for a while, maybe blocked, %dms\n", //
clientId, //
mq, //
diff));
}
}
}
}
return sb.toString();
}
public TreeMap getMqTable() {
return mqTable;
}
public void setMqTable(TreeMap mqTable) {
this.mqTable = mqTable;
}
public TreeMap getStatusTable() {
return statusTable;
}
public void setStatusTable(TreeMap statusTable) {
this.statusTable = statusTable;
}
public String formatString() {
StringBuilder sb = new StringBuilder();
// 1
{
sb.append("#Consumer Properties#\n");
Iterator> it = this.properties.entrySet().iterator();
while (it.hasNext()) {
Entry next = it.next();
String item = String.format("%-40s: %s\n", next.getKey().toString(), next.getValue().toString());
sb.append(item);
}
}
// 2
{
sb.append("\n\n#Consumer Subscription#\n");
Iterator it = this.subscriptionSet.iterator();
int i = 0;
while (it.hasNext()) {
SubscriptionData next = it.next();
String item = String.format("%03d Topic: %-40s ClassFilter: %-8s SubExpression: %s\n", //
++i, //
next.getTopic(), //
next.isClassFilterMode(), //
next.getSubString());
sb.append(item);
}
}
// 3
{
sb.append("\n\n#Consumer Offset#\n");
sb.append(String.format("%-32s %-32s %-4s %-20s\n", //
"#Topic", //
"#Broker Name", //
"#QID", //
"#Consumer Offset"//
));
Iterator> it = this.mqTable.entrySet().iterator();
while (it.hasNext()) {
Entry next = it.next();
String item = String.format("%-32s %-32s %-4d %-20d\n", //
next.getKey().getTopic(), //
next.getKey().getBrokerName(), //
next.getKey().getQueueId(), //
next.getValue().getCommitOffset());
sb.append(item);
}
}
// 4
{
sb.append("\n\n#Consumer MQ Detail#\n");
sb.append(String.format("%-32s %-32s %-4s %-20s\n", //
"#Topic", //
"#Broker Name", //
"#QID", //
"#ProcessQueueInfo"//
));
Iterator> it = this.mqTable.entrySet().iterator();
while (it.hasNext()) {
Entry next = it.next();
String item = String.format("%-32s %-32s %-4d %s\n", //
next.getKey().getTopic(), //
next.getKey().getBrokerName(), //
next.getKey().getQueueId(), //
next.getValue().toString());
sb.append(item);
}
}
// 5
{
sb.append("\n\n#Consumer RT&TPS#\n");
sb.append(String.format("%-32s %14s %14s %14s %14s %18s %25s\n", //
"#Topic", //
"#Pull RT", //
"#Pull TPS", //
"#Consume RT", //
"#ConsumeOK TPS", //
"#ConsumeFailed TPS", //
"#ConsumeFailedMsgsInHour"//
));
Iterator> it = this.statusTable.entrySet().iterator();
while (it.hasNext()) {
Entry next = it.next();
String item = String.format("%-32s %14.2f %14.2f %14.2f %14.2f %18.2f %25d\n", //
next.getKey(), //
next.getValue().getPullRT(), //
next.getValue().getPullTPS(), //
next.getValue().getConsumeRT(), //
next.getValue().getConsumeOKTPS(), //
next.getValue().getConsumeFailedTPS(), //
next.getValue().getConsumeFailedMsgs()//
);
sb.append(item);
}
}
// 6
if (this.jstack != null) {
sb.append("\n\n#Consumer jstack#\n");
sb.append(this.jstack);
}
return sb.toString();
}
public String getJstack() {
return jstack;
}
public void setJstack(String jstack) {
this.jstack = jstack;
}
public Map getStackTraceElementMap() {
return stackTraceElementMap;
}
public void setStackTraceElementMap(Map stackTraceElementMap) {
this.stackTraceElementMap = stackTraceElementMap;
}
}