Producer
消息发送
producer start
producer启动过程如下图
public void start(final boolean startFactory) throws MQClientException {
switch (this.serviceState) {
case CREATE_JUST:
this.serviceState = ServiceState.START_FAILED;
// check GroupName
this.checkConfig();
// 改变ClientConfig.instanceName为pid
if (!this.defaultMQProducer.getProducerGroup().equals(MixAll.CLIENT_INNER_PRODUCER_GROUP)) {
this.defaultMQProducer.changeInstanceNameToPID();
}
// 初始化mQClientFactory为MQClientInstance,并将该实例加入factoryTable
this.mQClientFactory = MQClientManager.getInstance().getAndCreateMQClientInstance(this.defaultMQProducer, rpcHook);
// 将producer注册到MQClientInstance.producerTbale
boolean registerOK = mQClientFactory.registerProducer(this.defaultMQProducer.getProducerGroup(), this);
if (!registerOK) {
this.serviceState = ServiceState.CREATE_JUST;
throw new MQClientException("The producer group[" + this.defaultMQProducer.getProducerGroup()
+ "] has been created before, specify another name please." + FAQUrl.suggestTodo(FAQUrl.GROUP_NAME_DUPLICATE_URL),
null);
}
// 保存topic对应的routeInfo
this.topicPublishInfoTable.put(this.defaultMQProducer.getCreateTopicKey(), new TopicPublishInfo());
if (startFactory) {
// 启动MQClientInstance
mQClientFactory.start();
}
log.info("the producer [{}] start OK. sendMessageWithVIPChannel={}", this.defaultMQProducer.getProducerGroup(),
this.defaultMQProducer.isSendMessageWithVIPChannel());
this.serviceState = ServiceState.RUNNING;
break;
case RUNNING:
case START_FAILED:
case SHUTDOWN_ALREADY:
throw new MQClientException("The producer service state not OK, maybe started once, "//
+ this.serviceState//
+ FAQUrl.suggestTodo(FAQUrl.CLIENT_SERVICE_NOT_OK),
null);
default:
break;
}
// 启动的时候向所有的broker发送heartbeat
this.mQClientFactory.sendHeartbeatToAllBrokerWithLock();
}
消息发送流程
消息发送过程:先由producer封装通过netty发送到broker,然后由broker进行保存,过程如下
============================= producer发送消息 =============================
主要逻辑在DefaultMQProducerImpl.sendDefaultImpl
- 获取topicRouteInfo
DefaultMQProducerImpl.tryToFindTopicPublishInfo
->
MQClientInstance.updateTopicRouteInfoFromNameServer
private final ConcurrentHashMap<String/* group */, MQProducerInner> producerTable:放置所有的producer
updateTopicRouteInfoFromNameServer
- 获取topicRouteInfo
- 然后遍历producerTable,更新所有producer的topicRouteInfo
- 遍历consumerTable,更新所有的consumer的topicSubscribeInfo
- 加入topicRouteTable
->
MQClientAPIImpl.getTopicRouteInfoFromNameServer
通过netty向nameServer发出请求,请求topicRouteInfo
- 选取一个messageQueue
从messageQueueList取一个MessageQueue - netty发送消息
DefaultMQProducer.sendKernelImpl,
============================= broker接收消息 ===&#