C-DefaultMQProducer C-DefaultMQProducerImpl method(sendDefaultImpl-sendKernelImpl-)
M-sendKernelImpl
C-MQClientInstance -MQClientAPIImpl-M(sendMessage-) 构建-RemotingCommand(1.构建请求头 2.填充消息体)
-NettyRemotingClient
-NettyRemotingAbstract-M(invokeSyncImpl);最终发送消息抽象类.组装 RemotingCommand-)
1.找路由,Producer从namesrv获取的到Topic_A路由信息TopicPublishInfo
2.找队列,随机算法
RocketMQ(六)发消息的时候选择queue的算法有哪些? - 苏先生139 - 博客园
3.发消息,NettyRemotingClient NettyRemotingAbstract 通讯原理netty发送
RocketMQ原理解析-producer 2.如何发送消息_斩秋的专栏-优快云博客_rocketmq发送消息原理
RocketMQ原理学习---生产者普通消息发送_井底之蛙-优快云博客
第一次发消息,topictable缓存无 TopicPublishInfo 信息,此时客户端要与nameServer交互获取topic对应broker信息,至此知道了发送到哪个broker
TopicPublishInfo 信息
ThreadLocalIndex
最终的选择队列算法,random.nextInt(),算一个随机数,用随机数对队列总和取余
ThreadLocal在这里啥意思?随机数,线程隔离
自己测试每次创建producer都是不同线程,每次都是生产新的随机数,显然这样算法不好,实际场景应该是一个生产者线程,或者比较少,取出之前值加1,取到下一个队列。生产者到底几个线程?
public class ThreadLocalIndex {
private final ThreadLocal<Integer> threadLocalIndex = new ThreadLocal<Integer>();
private final Random random = new Random();
public int incrementAndGet() {
Integer index = this.threadLocalIndex.get();
if (null == index) {
index = Math.abs(random.nextInt());
this.threadLocalIndex.set(index);
}
this.threadLocalIndex.set(++index);
return Math.abs(index);
}
@Override
public String toString() {
return "ThreadLocalIndex{" +
"threadLocalIndex=" + threadLocalIndex.get() +
'}';
}
}
public MessageQueue selectOneMessageQueue() {
int index = this.sendWhichQueue.incrementAndGet();
int pos = Math.abs(index) % this.messageQueueList.size();
if (pos < 0)
pos = 0;
return this.messageQueueList.get(pos);
}
最终发送消息的抽象类