org.apache.rocketmq.client.exception.MQClientException: No route info of this topic
com.alibaba.rocketmq.client.exception.MQClientException: Send [1] times, still failed, cost [3003]ms, Topic: WaybillTopicBOSServer, BrokersSent: [broker-a, null, null]
…
…
…
Caused by: com.alibaba.rocketmq.remoting.exception.RemotingConnectException: connect to <> failed
一共有四个原因:
1 brocker买有连接到mqnameserv
2 producer没有连接到mqnameserv
3 topic没有创建
4 防火墙
说明:
rocktMq中nameserv相当于一个zookeeper,充当一个注册的角色,所以brocker和我们的代码producer是通过nameserv来进行同行的。
brocker的启动命令中 -n xxxx:9876 就是指定 mqnameserv ,producer的代码中 也是 producer.setNamesrvAddr("xxxx:9876");
,这里都是指定的mqnameserv。
3 问题 在brocker的启动命令中加入autoCreateTopicEnable=true
就可以了
sh mqbroker -n 10.0.1.1:9876 autoCreateTopicEnable=true
4 问题 关闭防火墙就可以了 service iptables stop
1 2 问题
可以自己先到DefaultMQProducerImpl
这个类中查看源码,可以看到No route info of this topic是在connect to <> failed 错误的下面的,所以可以自己看源码,一个一个解决。
有人说autoCreateTopicEnable=true 是不行的 https://blog.csdn.net/guiliguiwang/article/details/79852556 ,所以想到了手动创建topic https://www.jianshu.com/p/345aaa18f71d (不是真正的原因)
有人说禁用网卡https://linux.cn/article-10844-1.html?pr (不管用)
有人说关闭vip通道https://www.cnblogs.com/zhjh256/p/6944431.html (不行,我的rockemq版本不支持这个方法)
有人说 https://my.oschina.net/u/3476125/blog/897429 (终于成功了)
方法就是修改brocker.conf 配置文件中的内容 brockerIP1,当然这个方法,很多博客中有提到,但是对我没有用。。。
这里引用一下上面这位作者的内容
先上结论
需要在启动的时候导入配置文件
#进入rocketmq根目录 cd incubator-rocketmq/distribution/target/apache-rocketmq
#编写配置文件,并写好配置 echo “brokerIP1=10.2.x.x” > broker.properties
#启动 mqnamesrv nohup sh bin/mqnamesrv &#重点:mrbroker 启动时通过 -c 加载配置文件 nohup sh bin/mqbroker -n ${namesrvIp}:9876 -c
/opt/rocketmq/incubator-rocketmq/distribution/target/apache-rocketmq/broker.properties
&原理:
rpcketMq broker的启动
rocketMq的broker 启动类
org.apache.rocketmq.broker.BrokerStartup 启动的时候会读取代码中的默认配置,关于
broker的配置在org.apache.rocketmq.common.BrokerConfig 中,根据源代码可以得知,broker使用的默认IP为本机Ip
brokerIP1 = RemotingUtil.getLocalAddress(); 得到选取ip的思路是,遍历本地的所有网卡ip,过滤掉
“127.0” 和“192.168”开头的ip地址然后得到第一个ip,为本机ip。
问题:
当这台机器有很多别的网卡(如:安装docker后),broker使用的ip,就可能会导致我们的客户端无法连接。
解决:
rockerMq,在加载默认配置后,根据,启动时是否包含 -c 参数
if (commandLine.hasOption(‘c’)) 确定是否执行代码加载额外配置文件
加载时,通过反射的方式,根据配置文件中的键值对,赋值到 BrokerConfig中对应的属性中。
最后:
rocketMq启动时会打印出所有“重要的配置” (被@ImportantField所注解的属性),
通过打印的 brokerIP1 的属性,就可以知道,配置是否成功了
引用中的内容好好看好好学! 这一波超级帅! 超 ! 级! 帅!
我的问题和这位作者一样,因为有学习过docker,在机器中有docker的网卡,所以导致,brocker总是代理到虚拟的网卡,我也意识到了这个问题,上面我有找禁用网卡的办法,可是还是不行。
看图
这里箭头所指的ip就是 brocker 的 ip和port,可以通过ifconfig查看和自己的docker网卡ip,一样,即使你禁用了也是不行的。
ps: 10911 是brocker的 9876 是mqnameserv的 ,分清楚
真正的解决办法就是修改 conf 目录中的brocker.conf 添加 brokerIP1=你的ip
,这里填写的ip如果是公网的就填公网ip,命令curl ifconfig.me
,如果你在局域网,就写局域网ip
就行。
sh mqbroker -n localhost:9876 -c ../conf/broker.conf autoCreateTopicEnable=true
这里的ip写localhost就行了,不影响,主要是后面的brocker.conf 里面的内容。
运行完了之后一定注意看
没错还是这个图中的箭头,是不是你配置的brocker.conf 中的ip
ps:因为brocker.conf是conf文件不是properties,所以可能你早就注意到了这个问题,可是brockerIP1=xxxx这个,为了测试方便,你用# 注释了,悲哀,这样是注释不掉的,只会导致自己的配置失效,所以在brocker.conf配置文件中不要通过#注释,配置的不对了删除重新写,这段话写的有点不容易理解,有灵性的人秒懂。
因为配置了docker虚拟ip导致,brocker总是代理到docker的虚拟ip上
rocketmq选取ip的思路是,遍历本地的所有网卡ip,过滤掉“127.0” 和“192.168”开头的ip地址,然后得到第一个ip,为本机ip。所以总是代理到docker的ip上了。
在broker.conf配置文件中添加配置 brokerIP1=需要指定的ip
运行命令:
sh mqbroker -n localhost:9876 -c ../conf/broker.conf autoCreateTopicEnable=true
创建topic
sh mqadmin updateTopic -n 10.0.1.2:9876 -b 10.0.1.1:10911 -t TopicA-test
查看topic
/mqadmin TopicRoute -n 10.0.1.25:9876 -t TopicA-test
查看是否注册了brocker
sh mqadmin clusterList -n localhost:9876