接着上篇文章我们,我们说了 MQClientId ,MQClientInstance是一个比较重要的概念,那么这个到底用在那个地方了呢?
我们先记住MQClientInstance是与MQ broken进行交互的载体,我们再来下面获取MQClientInstance的方式.
public MQClientInstance getOrCreateMQClientInstance(final ClientConfig clientConfig, RPCHook rpcHook) {
//获取MqClientId,此处我们发现 MQClientId在生成MQClientInstance需要用到
String clientId = clientConfig.buildMQClientId();
/*
* factoryTable是一个ConcurrentMap的结果,key就是 MQClientId
*/
MQClientInstance instance = this.factoryTable.get(clientId);
if (null == instance) {
instance =
new MQClientInstance(clientConfig.cloneClientConfig(),
this.factoryIndexGenerator.getAndIncrement(), clientId, rpcHook);
MQClientInstance prev = 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;
}
配合代码里的注释,所以当我们需要获取MQClientInstance对象与broker进行交互的时候,那我们我们就先需要先获取MQClientInstance ,那么如果获取MQClientInstance, MQClientInstance存放在一个类似Map的结构提里, MQClientId 就是获取MQClientInstance的key.
所以我们回顾一下,上篇文章中写的RocketMQ在4.9.0以上及一下版本获取MQClientId的差异,我们可以假设一下场景:
我们先假设RocketMQ的版本是4.9.0一下,那么我们再看看4.9.0以下的版本
public void changeInstanceNameToPID() {
if (this.instanceName.equals("DEFAULT")) {
this.instanceName = String.valueOf(UtilAll.getPid());
}
}
假如我们的项目里配置了2个以上的MQ集群,当我们没有主动设置instanceName的时候,我们会发现,生成的MQClientId是一样,而存放MQClientInstance是一个map接口,如果key是一样的,那么就意味着,程序里虽然配置里2个MQ集群,但是实际上MAP里却只有一个MQClientInstance,所以当我们在使用RocketMQ-4.9.0以下版本的时候, 且项目里配置了2个及以上MQ集群的时候,一定要配置instanceName属性, 所以我还是建议在4.9.0以下版本的时候,都配置上instanceName属性.
我们再看看4.9.0及以上版本的变化.
public void changeInstanceNameToPID() {
if (this.instanceName.equals("DEFAULT")) {
this.instanceName = UtilAll.getPid() + "#" + System.nanoTime();
}
}
其实4.9.0及以上的版本,就是在InstanceName后面加了一个时间戳. 其实这样就可以避免当我们没有设置instanceName的时候,且项目里配置了2个及以上MQ集群的时候,最后根据instanceName生成MQClientID的时候,不会出现相同的MQClientId.
总结
在同一个工程里,一个MQ集群就只需要一个MQ Producer. 如果MQ集群是根据BU划分的话,MQ Producer的命名最好跟BU名保持一致,切记不要涉及到要发消息,自己就新建一个跟业务名称相关的Producer, 这样除了占用内存之外,并无其他用户.