前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >org.apache.rocketmq.client.exception.MQClientException: No route info of this topic

org.apache.rocketmq.client.exception.MQClientException: No route info of this topic

作者头像
johnhuster的分享
发布2022-03-29 14:45:15
2.9K0
发布2022-03-29 14:45:15
举报
文章被收录于专栏:johnhuster

笔者最近在使用rocketmq时,使用部署在docker中的rocketmq就会报“org.apache.rocketmq.client.exception.MQClientException: No route info of this topic”异常,win10本地启动同版本的rocketmq release库没有任何问题,搜索了许久仍然没有找到问题,关于这个问题,部分原因在笔者,笔者没有完全按照http://rocketmq.apache.org/docs/simple-example/ 里面的demo引入下面的rocketmq-client依赖,而是引入的rocketmq-spring-boot-starter这个依赖,示例代码如下:

代码语言:javascript
复制
@Test
public  void send() throws MQClientException, UnsupportedEncodingException, RemotingException, InterruptedException, MQBrokerException {
    //Instantiate with a producer group name.
    DefaultMQProducer producer = new
            DefaultMQProducer("my-group1");
    //rocketmq nameserver地址
    producer.setNamesrvAddr("172.21.52.27:9876");
    producer.start();
    Message msg = new Message("test" /* Topic */,
            "TagA" /* Tag */,
            ("Hello RocketMQ ").getBytes("utf-8") /* Message body */
    );
    //Call send message to deliver message to one of brokers.
    SendResult sendResult = producer.send(msg);
    System.out.printf("%s%n", sendResult);
    //Shut down once the producer instance is not longer in use.
    producer.shutdown();
}

经过跟踪发现标红部分的代码根本没有起作用,为什么没起作用呢,下面看下DefaultMQProducer的构造方法:

代码语言:javascript
复制
    public DefaultMQProducer(String producerGroup, RPCHook rpcHook) {
        this.log = ClientLogger.getLog();
        this.createTopicKey = "TBW102";
        this.defaultTopicQueueNums = 4;
        this.sendMsgTimeout = 3000;
        this.compressMsgBodyOverHowmuch = 4096;
        this.retryTimesWhenSendFailed = 2;
        this.retryTimesWhenSendAsyncFailed = 2;
        this.retryAnotherBrokerWhenNotStoreOK = false;
        this.maxMessageSize = 4194304;
        this.traceDispatcher = null;
        this.producerGroup = producerGroup;
        //创建DefaultMQProducerImpl对象
        this.defaultMQProducerImpl = new DefaultMQProducerImpl(this, rpcHook);
    }


    //发送消息
    public SendResult send(Message msg) throws MQClientException, RemotingException, MQBrokerException, InterruptedException {
        return this.defaultMQProducerImpl.send(msg);
    }

从send方法以及DefaultMQProducer的构造方法可以看出,引入rocketmq-spring-boot-starter引入后导致MQClientInstance实例被提前创建,提前创建使用的是application.yml文件中配置:

代码语言:javascript
复制
rocketmq:
  name-server: 127.0.0.1:9876
  producer:
    group: my-group

该配置里面使用的就是127.0.0.1 而不是docker中部署的nameserver地址,虽然使用producer.setNamesrvAddr("172.21.52.27:9876")设置了rocketmq nameserver地址,但是其实是无效的,具体原因可以在MQClientManager类getAndCreateMQClientInstance方法查看,

代码语言:javascript
复制
public MQClientInstance getAndCreateMQClientInstance(ClientConfig clientConfig, RPCHook rpcHook) {
    String clientId = clientConfig.buildMQClientId();
    MQClientInstance instance = (MQClientInstance)this.factoryTable.get(clientId);
    if (null == instance) {
        instance = new MQClientInstance(clientConfig.cloneClientConfig(), this.factoryIndexGenerator.getAndIncrement(), clientId, rpcHook);
        MQClientInstance prev = (MQClientInstance)this.factoryTable.putIfAbsent(clientId, instance);
        if (prev != null) {
            instance = prev;
            log.warn("Returned Previous MQClientInstance for clientId:[{}]", clientId);
        } else {
            log.info("Created new MQClientInstance for clientId:[{}]", clientId);
        }
    }

    return instance;
}

由于引入rocketmq-spring-boot-starter导致getAndCreateMQClientInstance过早被创建,所以后续同一clientId不再创建MQClientInstance而使用最初创建的实例!

产生问题的原因在于最初application.proerties配置的是127.0.0.1:9876 虽然application.yml配对了地址,但是由于properties文件优先级比yaml文件高,导致一直使用的是127.0.0.1:9876这个错误地址,但是本地没有开启rocketmq服务,所以一直报"org.apache.rocketmq.client.exception.MQClientException: No route info of this topic"这个异常,搜索了很多最终都没有解决问题,最终单步调试解决了该问题。

PS:

1、是rocketmq的错误提示信息不够细,如果报connection exception之类的异常,也许早就解决了这个问题,但是却报出了很多场景都可能出现的”org.apache.rocketmq.client.exception.MQClientException: No route info of this topic“这个错误

2、引入rocketmq-spring-boot-starter以来时不要使用DefaultMQProducer发送信息

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/12/06 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器镜像服务
容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档