問題
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

