解决rocketmq-client查询手动发送消息异常问题

 更新时间:2023年08月29日 15:26:27   作者:小淼同学  
这篇文章主要介绍了解决rocketmq-client查询手动发送消息异常问题,具有很好的参考价值,希望对大家大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

rocketmq-client查询手动发送消息异常

今天处理rocketmq的后台的一些问题

下面这个问题是你也用网上4.x的rocketmq版本的监控后台,才会出现的

MQClientException: CODE: 208 DESC: query message by id finished, but no message.

这个是我们用rocketmq-client手动发送消息的时候,再去查看消息详情的时候遇到的问题,会报错,消息找不到

这是由于查询出来的mq消息,这些消息的msgId,不是真的msgId,而是UniqueKey

为什么会这样呢,我们来看一段源码

public static List<MessageExt> decodes(java.nio.ByteBuffer byteBuffer, final boolean readBody) {
        List<MessageExt> msgExts = new ArrayList<MessageExt>();
        while (byteBuffer.hasRemaining()) {
            MessageExt msgExt = clientDecode(byteBuffer, readBody);
            if (null != msgExt) {
                msgExts.add(msgExt);
            } else {
                break;
            }
        }
        return msgExts;
    }

1.以上是解析从broker获取到的消息

  public static MessageExt clientDecode(java.nio.ByteBuffer byteBuffer, final boolean readBody) {
        return decode(byteBuffer, readBody, true, true);
    }

2.注意第四个参数是true

它代表是否是client端,就是监控端

 public static MessageExt decode(
        java.nio.ByteBuffer byteBuffer, final boolean readBody, final boolean deCompressBody, final boolean isClient) {
        try {
            MessageExt msgExt;
            //1.重点看这里
            if (isClient) {
                msgExt = new MessageClientExt();
            } else {
                msgExt = new MessageExt();
            }
            //此处省略
            ...........
            ByteBuffer byteBufferMsgId = ByteBuffer.allocate(MSG_ID_LENGTH);
            String msgId = createMessageId(byteBufferMsgId, msgExt.getStoreHostBytes(), msgExt.getCommitLogOffset());
            msgExt.setMsgId(msgId);
            //2.重点看这里
            if (isClient) {
                ((MessageClientExt) msgExt).setOffsetMsgId(msgId);
            }
            return msgExt;
        } catch (Exception e) {
            byteBuffer.position(byteBuffer.limit());
        }
        return null;
    }

3.MessageClientExt主要是这个对象惹的祸

老的版本mq就是一个 MessageExt

我们再来看看这个对象为什么惹祸了

public class MessageClientExt extends MessageExt {
    public String getOffsetMsgId() {
        return super.getMsgId();
    }
    public void setOffsetMsgId(String offsetMsgId) {
        super.setMsgId(offsetMsgId);
    }
    /**
    * 没错就是这里,默认拿的是属性里的UNIQ_KEY
    **/
    @Override
    public String getMsgId() {
        String uniqID = MessageClientIDSetter.getUniqID(this);
        if (uniqID == null) {
            return this.getOffsetMsgId();
        } else {
            return uniqID;
        }
    }
    public void setMsgId(String msgId) {
        //DO NOTHING
        //MessageClientIDSetter.setUniqID(this);
    }
}

所以知道了问题,就好解决了

我是在显示类里面做相应的处理,贴下我的处理方式,我是在  MessageView.class里处理

 public static MessageView fromMessageExt(MessageExt messageExt) {
        MessageView messageView = new MessageView();
        BeanUtils.copyProperties(messageExt, messageView);
        if (messageExt.getBody() != null) {
            messageView.setMessageBody(new String(messageExt.getBody(), Charsets.UTF_8));
        }
        //主要是这里判断下,是否是这个类,是就把原来的msgId拿出来
        if(messageExt instanceof MessageClientExt){
            MessageClientExt ext =   (MessageClientExt) messageExt;
            messageView.setMsgId(ext.getOffsetMsgId());
        }
        return messageView;
    }

总结

好了,这里就总结下这个问题

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java多线程编程基石ThreadPoolExecutor示例详解

    Java多线程编程基石ThreadPoolExecutor示例详解

    这篇文章主要为大家介绍了Java多线程编程基石ThreadPoolExecutor示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • Java中extends一定是代表继承吗?

    Java中extends一定是代表继承吗?

    今天小编就为大家分享一篇关于Java中extends一定是代表继承吗?,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • 深入学习java中的Groovy 和 Scala 类

    深入学习java中的Groovy 和 Scala 类

    本文将探讨三种下一代 JVM 语言:Groovy、Scala 和 Clojure,比较并对比新的功能和范例,让 Java 开发人员对自己近期的未来发展有大体的认识。,需要的朋友可以参考下
    2019-06-06
  • Java实现简单堆栈代码

    Java实现简单堆栈代码

    这篇文章主要为大家详细介绍了Java实现简单堆栈代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-12-12
  • Java登录功能实现token生成与验证

    Java登录功能实现token生成与验证

    这篇文章介绍了Java登录功能实现token生成与验证,文中通过示例代码介绍的非常详细。对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-12-12
  • SpringBoot项目集成日志的实现方法

    SpringBoot项目集成日志的实现方法

    这篇文章主要介绍了SpringBoot项目集成日志的实现方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-02-02
  • 一文了解Spring中拦截器的原理与使用

    一文了解Spring中拦截器的原理与使用

    在web开发中,拦截器是经常用到的功能。它可以帮我们预先设置数据以及统计方法的执行效率等等。今天就来详细的谈一下spring中的拦截器,需要的可以参考一下
    2022-06-06
  • Java由浅入深通关抽象类与接口下

    Java由浅入深通关抽象类与接口下

    在类中没有包含足够的信息来描绘一个具体的对象,这样的类称为抽象类,接口是Java中最重要的概念之一,它可以被理解为一种特殊的类,不同的是接口的成员没有执行体,是由全局常量和公共的抽象方法所组成,本文给大家介绍Java抽象类和接口,感兴趣的朋友一起看看吧
    2022-04-04
  • 浅谈HashMap在高并发下的问题

    浅谈HashMap在高并发下的问题

    这篇文章主要介绍了HashMap在高并发下的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • 利用Java Set 去除重复object的方法

    利用Java Set 去除重复object的方法

    下面小编就为大家带来一篇利用Java Set 去除重复object的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-01-01

最新评论