版本:4.2.0
producer启动代码
public void start(boolean startFactory) throws MQClientException {
switch(this.serviceState) {
case CREATE_JUST:
this.serviceState = ServiceState.START_FAILED;
//检查producerGroup
this.checkConfig();
if (!this.defaultMQProducer.getProducerGroup().equals("CLIENT_INNER_PRODUCER")) {
this.defaultMQProducer.changeInstanceNameToPID();
}
//生成一个MQClientInstance实例
this.mQClientFactory = MQClientManager.getInstance().getAndCreateMQClientInstance(this.defaultMQProducer, this.rpcHook);
//注册到table中
boolean registerOK = this.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("http://rocketmq.apache.org/docs/faq/"), (Throwable)null);
} else {
//注册默认topic信息,定时任务会从nameServer拉取信息并更新
this.topicPublishInfoTable.put(this.defaultMQProducer.getCreateTopicKey(), new TopicPublishInfo());
if (startFactory) {
//启动相关的组件、定时任务
this.mQClientFactory.start();
}
this.log.info("the producer [{}] start OK. sendMessageWithVIPChannel={}", this.defaultMQProducer.getProducerGroup(), this.defaultMQProducer.isSendMessageWithVIPChannel());
this.serviceState = ServiceState.RUNNING;
}
default:
this.mQClientFactory.sendHeartbeatToAllBrokerWithLock();
return;
case RUNNING:
case START_FAILED:
case SHUTDOWN_ALREADY:
throw new MQClientException("The producer service state not OK, maybe started once, " + this.serviceState + FAQUrl.suggestTodo("http://rocketmq.apache.org/docs/faq/"), (Throwable)null);
}
}
MQClientInstance是什么呢?
public MQClientInstance(ClientConfig clientConfig, int instanceIndex, String clientId, RPCHook rpcHook) {
this.log = ClientLogger.getLog();
this.bootTimestamp = System.currentTimeMillis();
this.producerTable = new ConcurrentHashMap();
this.consumerTable = new ConcurrentHashMap();
this.adminExtTable = new ConcurrentHashMap();
this.topicRouteTable = new ConcurrentHashMap();
this.lockNamesrv = new ReentrantLock();
this.lockHeartbeat = new ReentrantLock();
this.brokerAddrTable = new ConcurrentHashMap();
this.brokerVersionTable = new ConcurrentHashMap();
this.scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
public Thread newThread(Runnable r) {
return new Thread(r, "MQClientFactoryScheduledThread");
}
});
this.sendHeartbeatTimesTotal = new AtomicLong(0L);
this.serviceState = ServiceState.CREATE_JUST;
this.random = new Random();
this.clientConfig = clientConfig;
this.instanceIndex = instanceIndex;
this.nettyClientConfig = new NettyClientConfig();
this.nettyClientConfig.setClientCallbackExecutorThreads(clientConfig.getClientCallbackExecutorThreads());
this.nettyClientConfig.setUseTLS(clientConfig.isUseTLS());
this.clientRemotingProcessor = new ClientRemotingProcessor(this);
// MQClientAPIImpl初始化会生成NettyRemotingClient
this.mQClientAPIImpl = new MQClientAPIImpl(this.nettyClientConfig, this.clientRemotingProcessor, rpcHook, clientConfig);
if (this.clientConfig.getNamesrvAddr() != null) {
this.mQClientAPIImpl.updateNameServerAddressList(this.clientConfig.getNamesrvAddr());
this.log.info("user specified name server address: {}", this.clientConfig.getNamesrvAddr());
}
this.clientId = clientId;
this.mQAdminImpl = new MQAdminImpl(this);
this.pullMessageService = new PullMessageService(this);
this.rebalanceService = new RebalanceService(this);
this.defaultMQProducer = new DefaultMQProducer("CLIENT_INNER_PRODUCER");
this.defaultMQProducer.resetClientConfig(clientConfig);
this.consumerStatsManager = new ConsumerStatsManager(this.scheduledExecutorService);
}
从初始化可以看出来MQClientInstance是producer的核心,包括了brokerAddr、topic路由信息、netty组件、拉取消息组件、消费端messageQueue均衡组件等等。拉取消息和mq均衡是consumer的核心功能。
那么MQClientInstance启动的时候又做了什么呢?
public void start() throws MQClientException {
synchronized(this) {
switch(this.serviceState) {
case CREATE_JUST:
this.serviceState = ServiceState.START_FAILED;
if (null == this.clientConfig.getNamesrvAddr()) {
this.mQClientAPIImpl.fetchNameServerAddr();
}
// 启动netty组件
this.mQClientAPIImpl.start();
// 启动定时任务
this.startScheduledTask();
。。。
this.log.info("the client factory [{}] start OK", this.clientId);
this.serviceState = ServiceState.RUNNING;
case RUNNING:
case SHUTDOWN_ALREADY:
default:
return;
case START_FAILED:
throw new MQClientException("The Factory object[" + this.getClientId() + "] has been created before, and failed.", (Throwable)null);
}
}
}
定时任务
private void startScheduledTask() {
if (null == this.clientConfig.getNamesrvAddr()) {
this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
public void run() {
try {
// 定时抓取nameServer的地址
MQClientInstance.this.mQClientAPIImpl.fetchNameServerAddr();
} catch (Exception var2) {
MQClientInstance.this.log.error("ScheduledTask fetchNameServerAddr exception", var2);
}
}
}, 10000L, 120000L, TimeUnit.MILLISECONDS);
}
this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
public void run() {
try {
// 定时请求nameServer拉取TopicRouteData并更新本地缓存列表
MQClientInstance.this.updateTopicRouteInfoFromNameServer();
} catch (Exception var2) {
MQClientInstance.this.log.error("ScheduledTask updateTopicRouteInfoFromNameServer exception", var2);
}
}
}, 10L, (long)this.clientConfig.getPollNameServerInterval(), TimeUnit.MILLISECONDS);
this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
public void run() {
try {
// 定时清理下线的broker
MQClientInstance.this.cleanOfflineBroker();
// 定时向在线的broker master发送心跳包
MQClientInstance.this.sendHeartbeatToAllBrokerWithLock();
} catch (Exception var2) {
MQClientInstance.this.log.error("ScheduledTask sendHeartbeatToAllBroker exception", var2);
}
}
}, 1000L, (long)this.clientConfig.getHeartbeatBrokerInterval(), TimeUnit.MILLISECONDS);
。。。
}