2.rocketmq源代码学习---客户端消息发送

通过上一篇demo,发送消息关键方法为:DefaultMQProducer.send()方法 

通过send()方法,进入到内部关键代码,sendDefaultImpl();

方法有点长,我们先通过一个时序图,简单看一下方法的大致流程

 

2.rocketmq源代码学习---客户端消息发送_第1张图片

接下来,对图中重点的方法进行解析:

1、tryToFindTopicPublishInfo(),获取主题的队列配置 

该方法主要是获取主题的队列信息,当从本地内存中,获取不到时,从namesrv服务器获取主题配置信息

诶,问题来了,为什么要从namesrv服务器获取呢

这就要说说namesrv和broker了

broker:主要是做消息存储的

rocketmq作为消息中间件,肯定需要有高可用的保障策略,自然而然就引入了集群,由集群就能联想到 主从、双主、双从

在多个broker集群情况下,则需要一个中心来管理broker。

代码如下:

//获取主题的配置信息
private TopicPublishInfo tryToFindTopicPublishInfo(final String topic) {
        //1.topicPublishInfoTable相当于一层缓存,保存了topic的队列配置信息
        TopicPublishInfo topicPublishInfo = this.topicPublishInfoTable.get(topic);
        if (null == topicPublishInfo || !topicPublishInfo.ok()) {
            //2.当topicPublishInfoTable中没有时,从namesrv服务器获取主题的队列配置信息
            this.topicPublishInfoTable.putIfAbsent(topic, new TopicPublishInfo());
            this.mQClientFactory.updateTopicRouteInfoFromNameServer(topic);
            topicPublishInfo = this.topicPublishInfoTable.get(topic);
        }

        if (topicPublishInfo.isHaveTopicRouterInfo() || (topicPublishInfo != null && topicPublishInfo.ok())) {
            return topicPublishInfo;
        }
        else {
            this.mQClientFactory.updateTopicRouteInfoFromNameServer(topic, true, this.defaultMQProducer);
            topicPublishInfo = this.topicPublishInfoTable.get(topic);
            return topicPublishInfo;
        }
}

2、selectOneMessageQueue(),选择主题的一个队列 

该方法主要是选择主题的一个队列发送消息,选择的策略是怎么样的呢?通过代码可得知,是通过AtomaticInteger顺序轮询获取,这样就保证消息里面多个队列的消息几乎是均衡的。

哦,对了,队列是什么呢?

rocketmq将主题分成多个队列,通过多个队列实现消费端的负载均衡、顺序消费等巴拉巴拉很多功能。

上代码:
 

//选择一个消息队列,发送消息
 public MessageQueue selectOneMessageQueue(final String lastBrokerName) {
        if (lastBrokerName != null) {
            //AtomicInteger sendWhichQueue = new AtomicInteger(0);
            //sendSwitchQueue为自增的
            int index = this.sendWhichQueue.getAndIncrement();
            //发送时,轮询主题的消息队列,保障消息队列的均衡
            for (int i = 0; i < this.messageQueueList.size(); i++) {
                int pos = Math.abs(index++) % this.messageQueueList.size();
                MessageQueue mq = this.messageQueueList.get(pos);
                if (!mq.getBrokerName().equals(lastBrokerName)) {
                    return mq;
                }
            }

            return null;
        }
        else {
            int index = this.sendWhichQueue.getAndIncrement();
            int pos = Math.abs(index) % this.messageQueueList.size();
            return this.messageQueueList.get(pos);
        }
    }

3、sendKenelImpl(),终于到发送消息的核心代码了 

该方法主要是封装消息内容,通过netty向服务端发送请求。

2.rocketmq源代码学习---客户端消息发送_第2张图片

具体是怎么和服务端通信的,在《rocketmq源代码学习----客户端服务端通信》一章中再去详细说明。

 

你可能感兴趣的:(rocketmq源代码)