html idehtml id 重复,RocketMq中的traceId重复问题

背景

最近发现生产上mq的traceId有重复现象,理论上不一样消息消费,tracdId不该该相同,但为何有必定的几率会出现呢?

查询代码以下:java

protected ConsumeStatus consumeMsgSingle(MessageExt ext) {

log.debug("AbstractMessageListener-consumeMessage() msgId:{}, body:{}", ext.getMsgId(), new String(ext.getBody()));

String message = new String(ext.getBody());

//获取到key

String key = RocketMQUtils.concatKey(ext.getTopic(), ext.getTags());

//根据key从handleMap里获取到咱们的处理类

MessageProcessor messageProcessor = handleMap.get(key);

if (Objects.isNull(messageProcessor)) {

messageProcessor = handleMap.get(ext.getTopic());

}

Optional.ofNullable(messageProcessor).orElseThrow(() -> new RRException(String.format("未找到消息处理类, topic:%s, tag:%s", ext.getTopic(), ext.getTags())));

Object obj = null;

try {

//将String类型的message反序列化成对应的对象。

obj = messageProcessor.transferMessage(message);

if (obj instanceof MqMetaInfo) {

MqMetaInfo meta = (MqMetaInfo) obj;

MqMetaInfoConverter.fromExt(meta, ext);

}

generateMDC(ext);

} catch (Exception e) {

StringBuilder errMsg = new StringBuilder("对象反序列化失败, ")

.append("messageId: ")

.append(ext.getMsgId()).append("\n")

.append("msgBody: ")

.append(new String(ext.getBody())).append("\n")

.append("messageExt ")

.append(ext).append("\n")

.append("stackTrace: ")

.append(JSON.toJSONString(e.getStackTrace()));

log.error("AbstractMessageListener-consumeMessage() error:{}, msgId:{}, message:{}, errMsg:{}"

, e, ext.getMsgId(), new String(ext.getBody()), errMsg.toString());

throw new RRException(errMsg.toString());

}

//处理消息

boolean result = messageProcessor.handleMessage(obj);

if (!result) {

if (ext.getReconsumeTimes() > Integer.MAX_VALUE) {

return ConsumeStatus.SUCCESS;

}

return ConsumeStatus.FAIL;

}

return ConsumeStatus.SUCCESS;

}

generateMDC方法以下:

1460000039264924app

缘由分析

能够看到若是message中有traceId,则把traceId关联到该线程,并打印出来。但发现最终该方法执行完成后未作清理traceId的动做,即RocketMq的消费者用的是线程池,而线程回收后traceId依然绑定在该线程上,若是下次有消息过来消费则会有一样traceId出现

重现

消费者

@Slf4j

@Service(value = "multiConsumerDemoProcessor")

public class MultiConsumerDemoProcessor implements MessageProcessor {

@Override

public boolean handleMessage(String orderNo) {

log.info("开始消费:{}", orderNo);

try {

Thread.sleep(500);

} catch (InterruptedException e) {

e.printStackTrace();

}

return true;

}

@Override

public Class getClazz() {

return null;

}

@Override

public String transferMessage(String message) {

return message;

}

}

生产者

public class Producer {

public static void main(String[] args) throws MQClientException, InterruptedException {

DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");

producer.setNamesrvAddr("ip");

producer.start();

for (int i = 0; i < 10; i++)

try {

{

Message msg = new Message("multi-consumer-demo",

"demo",

"OrderID188",

"Hello world".getBytes(RemotingHelper.DEFAULT_CHARSET));

SendResult sendResult = producer.send(msg);

System.out.printf("%s%n", sendResult);

}

} catch (Exception e) {

e.printStackTrace();

}

//producer.shutdown();

}

}

运行结果:

1460000039264926

能够看到traceId是有重复的ide

解决

加上finally语句,释放traceId

1460000039264927ui

解决结果

1460000039264925

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值