背景:目前业务发展,需要向另外一个mq上发送消息,要保留原来的业务线,需要原来的生产者发送到老的mq中,新的业务线创建新的生产者需要链接到新的namesrv
老系统的MQ
DefaultMQProducer producer = new DefaultMQProducer("producer_group_a");
producer.setNamesrvAddr("老系统的namesrv");
producer.start();
新系统的MQ
DefaultMQProducer producer = new DefaultMQProducer("producer_group_a");
producer.setNamesrvAddr("新系统的namesrv");
producer.start();
结果所有的消息都会只发送到系统中,跟踪代码发现
根据clientId获取MQClientInstance
clientId获取的规则是:
MQ在发送消息会获取TopicPublishInfo
private TopicPublishInfo tryToFindTopicPublishInfo(final String topic) {
//获取本地缓存的信息
TopicPublishInfo topicPublishInfo = this.topicPublishInfoTable.get(topic);
if (null == topicPublishInfo || !topicPublishInfo.ok()) {
//本地为空创建新对象
this.topicPublishInfoTable.putIfAbsent(topic, new TopicPublishInfo());
//从namesrv中获取
this.mQClientFactory.updateTopicRouteInfoFromNameServer(topic);
//如果都没有使用默认的topic主题
topicPublishInfo = this.topicPublishInfoTable.get(topic);
}
if (topicPublishInfo.isHaveTopicRouterInfo() || topicPublishInfo.ok()) {
return topicPublishInfo;
} else {
this.mQClientFactory.updateTopicRouteInfoFromNameServer(topic, true, this.defaultMQProducer);
topicPublishInfo = this.topicPublishInfoTable.get(topic);
return topicPublishInfo;
}
}
远程namesrv获取TopicPublishInfo以及TopicRouteData(维护队列、broker的信息)
因为获取到了同一个MQClientInstance实例,导致另外一个MQ获取到的broker信息永远都是第一个加载出来的信息,所以会导致消息永远都会发送到一个MQ中
解决思路:获取不同的MQClientInstance实例,而MQClientInstance实例是通过
String clientId = clientConfig.buildMQClientId();
MQClientInstance instance = this.factoryTable.get(clientId);
结果就是所以改变一下clientId的值
因此获取的MQClientInstance是同一个实例,如果想要获取不同的实例,需要更改instanceName或者unitName,更改后的代码,解决问题
DefaultMQProducer producer = new DefaultMQProducer("producer_group_a");
producer.setNamesrvAddr("localhost:9876");
producer.setInstanceName("ssssss");
producer.start();
欢迎关注我的公众号,交流
回复 8888可以领取面试资料
版权声明:本文为u013099854原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。