为了记录自己学习RocketMQ源码,记录一下,顺便分享一下学习过程
RocketMQ版本为4.9.3源码,idea打开源码看着会直观一点
消费者启动类org.apache.rocketmq.client.impl.consumer.DefaultMQPushConsumerImpl,找到start()方法的最后一行代码
public synchronized void start() throws MQClientException {
......
......
......
//此处省略原有的代码
this.mQClientFactory.rebalanceImmediately();
}
this.mQClientFactory 是 org.apache.rocketmq.client.impl.factory.MQClientInstance 这个类的实例对象,mQClientFactory 是什么时候实例化的,在start()方法里有一行代码
switch (this.serviceState) {
case CREATE_JUST:
//此处省略n行代码
//此处
this.mQClientFactory = MQClientManager.getInstance().getOrCreateMQClientInstance(this.defaultMQPushConsumer, this.rpcHook);
进入一个MQClientManager类,看名字就知道是管理MQ客户端的一个类了,找到getOrCreateMQClientInstance方法,this.defaultMQPushConsumer继承了ClientConfig类,getOrCreateMQClientInstance方法可以接收参数this.defaultMQPushConsumer,返回一个MQClientInstance 对象
public MQClientInstance getOrCreateMQClientInstance(final ClientConfig clientConfig, RPCHook rpcHook) {
String clientId = clientConfig.buildMQClientId();
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;
}
上面代码有点扯远了, 进入方法rebalanceImmediately()代码如下
org.apache.rocketmq.client.impl.factory.MQClientInstance#rebalanceImmediately
public void rebalanceImmediately() {
this.rebalanceService.wakeup();
}
调用了rebalanceService的wakeup方法唤醒rebalanceService线程,此时我们去看看RebalanceService的run()方法,
public void run() {
log.info(this.getServiceName() + " service started");
while (!this.isStopped()) {
//这一行是等待默认20秒, waitInterval = 20
this.waitForRunning(waitInterval);
this.mqClientFactory.doRebalance();
}
log.info(this.getServiceName() + " service end");
}
调用了rebalanceService的wakeup方法唤醒rebalanceService线程,线程无需等待,消费者启动就立刻执行消费者负载均衡的方法逻辑了,至此,RocketMQ消费者启动,触发消费者负载均衡的源码逻辑分析完毕。