解决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;
    }

总结

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

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

相关文章

  • 详解Spring Boot实战之Rest接口开发及数据库基本操作

    详解Spring Boot实战之Rest接口开发及数据库基本操作

    本篇文章主要介绍了Spring Boot实战之Rest接口开发及数据库基本操作,具有一定的参考价值,有兴趣的可以了解一下
    2017-07-07
  • 学习Java的9张思维导图

    学习Java的9张思维导图

    这篇文章主要为大家详细介绍了学习Java的9张思维导图,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • idea搭建SSM框架遇踩的坑(附完整过程)

    idea搭建SSM框架遇踩的坑(附完整过程)

    最近准备搭建一个SSM框架,由于很久没有搭建了,一来就遇到各种问题,折腾了一天终于搞定了,特此记录一下遇到的问题,下面这篇文章主要给大家介绍了关于idea搭建SSM框架遇踩的坑,文中还附完整过程,需要的朋友可以参考下
    2023-04-04
  • Java的@Transactional、@Aysnc、事务同步问题详解

    Java的@Transactional、@Aysnc、事务同步问题详解

    这篇文章主要介绍了Java的@Transactional、@Aysnc、事务同步问题详解,现在我们需要在一个业务方法中插入一个用户,这个业务方法我们需要加上事务,然后插入用户后,我们要异步的方式打印出数据库中所有存在的用户,需要的朋友可以参考下
    2023-11-11
  • idea中如何集成http请求

    idea中如何集成http请求

    这篇文章主要介绍了idea中如何集成http请求问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • 详解Spring中使用@within与@target的区别

    详解Spring中使用@within与@target的区别

    这篇文章主要介绍了Spring中使用@within与@target的一些区别,本文通过项目案例给大家详细分析,给大家介绍的非常详细,代码简单易懂,需要的朋友可以参考下
    2021-09-09
  • 关于application.yml基础配置以及读取方式

    关于application.yml基础配置以及读取方式

    这篇文章主要介绍了关于application.yml基础配置以及读取方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • 浅析Java中的访问控制权限

    浅析Java中的访问控制权限

    这篇文章主要介绍了浅析Java中的访问控制权限,在Java中,提供了四种访问权限控制,分别是默认访问权限、public、private以及protected,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • Java设计模式中的观察者模式

    Java设计模式中的观察者模式

    观察者模式定义对象之间的一种一对多的依赖关系,使得每当一个对象的状态发生变化时,其相关的依赖对象都可以得到通知并被自动更新。主要用于多个不同的对象对一个对象的某个方法会做出不同的反应
    2023-02-02
  • IDEA生成servlet程序的实现步骤

    IDEA生成servlet程序的实现步骤

    这篇文章主要介绍了IDEA生成servlet程序的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03

最新评论