官方示例异步发送消息异常:
org.apache.rocketmq.client.exception.MQClientException: No route info of this topic, TopicTest
按照RocketMQ官网的异步消息生产者中的《2.2 Send Messages Asynchronously》
创建了一个异步消息的生成者。如下:
public class AsyncProducer {
public static void main(String[] args) throws Exception {
//Instantiate with a producer group name.
DefaultMQProducer producer = new DefaultMQProducer("please_rename_unique_group_name");
// Specify name server addresses.
producer.setNamesrvAddr("localhost:9876");
//Launch the instance.
producer.start();
producer.setRetryTimesWhenSendAsyncFailed(0);
for (int i = 0; i < 100; i++) {
final int index = i;
//Create a message instance, specifying topic, tag and message body.
Message msg = new Message("TopicTest",
"TagA",
"OrderID188",
"Hello world".getBytes(RemotingHelper.DEFAULT_CHARSET));
producer.send(msg, new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
System.out.printf("%-10d OK %s %n", index,
sendResult.getMsgId());
}
@Override
public void onException(Throwable e) {
System.out.printf("%-10d Exception %s %n", index, e);
e.printStackTrace();
}
});
}
//Shut down once the producer instance is not longer in use.
producer.shutdown();
}
}
在我启动了namesrv、broker和consumer之后,运行该示例代码。
结果就出现了,无法找到Topic的异常
org.apache.rocketmq.client.exception.MQClientException: No route info of this topic, TopicTest
问题分析
我发现broker与namesrv的连接是没有问题的
然后我又在通过在mqbroker的启动参数上增加autoCreateTopicEnable=true
同样的,问题没有解决。
默认情况下 broker会自动创建话题
由于是异步消息,所以我猜测是否是由于主线程提前关闭,导致其他异步的线程也受到影响。于是我在producer.shutdown();的上方使主线程睡眠。
}
...
//Shut down once the producer instance is not longer in use.
Thread.sleep(3000); //延迟主线程的执行时间
producer.shutdown();
}
}
再次运行,发现问题解决。
官方解决思路
通过在RocketMQ官方提供 AsyncProducer.java中我发现,它使用到了CountDownLatch来解决这个异步问题。
CountDownLatch类的三个方法
-
void await() 调用这个方法的线程会被挂起,直到count值为0才继续执行。
-
boolean await(long
-
timeout, TimeUnit unit) 与await()类似,该方法需要设置超时时间,如果等待超过超时时间,则继续执行。
-
countDown() 将count值减1。 通过CountDownLatch的构造器就可以创建
官方解决代码示例如下
public class AsyncProducer {
public static void main(
String[] args) throws MQClientException
, InterruptedException
, UnsupportedEncodingException {
DefaultMQProducer producer = new DefaultMQProducer("Jodie_Daily_test");
producer.start();
producer.setRetryTimesWhenSendAsyncFailed(0);
int messageCount = 100;//发送消息数量
final CountDownLatch countDownLatch = new CountDownLatch(messageCount);//定义条件
for (int i = 0; i < messageCount; i++) {
try {
final int index = i;
Message msg = new Message("Jodie_topic_1023",
"TagA",
"OrderID188",
"Hello world".getBytes(RemotingHelper.DEFAULT_CHARSET));
producer.send(msg, new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
countDownLatch.countDown();
System.out.printf("%-10d OK %s %n", index, sendResult.getMsgId());
}
@Override
public void onException(Throwable e) {
countDownLatch.countDown();
System.out.printf("%-10d Exception %s %n", index, e);
e.printStackTrace();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
countDownLatch.await(5, TimeUnit.SECONDS);//达到100关闭生产(发送者)
producer.shutdown();
}
}
参考文章:https://blog.youkuaiyun.com/q1009020096/article/details/84543422