RocketMQ源码解析之broker(向namesrv注册)

原创不易,转载请注明出处


前言

之前我们介绍过namesrv在RocketMQ中充当着注册中心与元数据管理的角色,消息生产者发送消息的时候,需要定时的去namesrv上面拉取topic的有关信息,比如说某个topic有几个MessageQueue,每个MessageQueue在那个broker上面存储着,拿到这些数据之后,消息生产者就能根据某种规则,然后将消息发送到对应MessageQueue的broker上面,其中namesrv这些信息是怎么来的就与本文介绍的broker启动完成的时候向namesrv注册的流程有关,同时本文还看下namesrv是怎样处理broker注册请求的。

1.broker向namesrv注册

在broker初始化完成后,就会进行启动工作,BrokerController.start方法中有这么一行代码
在这里插入图片描述
我们进去看看这个方法干了啥
在这里插入图片描述
首先是去TopicConfigManager组件中,把本地的TopicConfig表中的数据与数据的版本封装成一个wrapper实体,这里先看下里面的到底是什么
在这里插入图片描述
topicConfigTable的key是topic名字, value就是该topic对应的配置信息,比如说写mq数量,读mq数量,还有权限等等。
dataVersion就是数据的版本,里面有一个计数器,版本发生了变化,计数器就+1。

接着就是设置权限了,有的broker是不允许读的或者是不允许写的,这个时候,就会将这个broker上面的所有topic对应的mq权限设置成不可读或者是不可写。

最后就是调用doRegisterBrokerAll方法进行注册。

接下来我们看看doRegisterBrokerAll方法干了啥。
在这里插入图片描述
这里主要是找到BokerOuterAPI组件的registerBrokerAll方法,这个BokerOuterAPI组件主要就是与namesrv打交道的,里面封装了注册,下线,获取namesrv地址等方法。
我们接着看下BokerOuterAPI的registerBrokerAll 方法。
该方法分为两个部分,一是封装请求,二是进行注册,我们这里先看下实体的封装。
在这里插入图片描述
可以看到请求头部分是封装了broker自己的基础信息,请求体中里面就放了上面我们介绍的那个wrapper。
接下来看看第二部分,看看是怎样注册的。
在这里插入图片描述
CountDownLatch这个这里就不多说了,不知道它是干嘛的同学可以找本并发编程的书籍研究下。
可以看到是for循环往线程池中添加向的namesrv进行注册的任务,多线程注册,这里注意的是往所有namesrv(就是你配置的那些namesrv地址)中注册,然后将结果放到registerBrokerResultList集合中,这个集合就是个普通的ArrayList,所以说这里可能会有并发问题。
最后就是countDownLatch等待所有的注册完成,可以看到,就算是超时也没事,超时时间默认是6s。关于是怎样发送请求的,我们这里不需要care了,这涉及到RocketMQ网络组件部分,我们后面会有专门的模块来剖析它,还有拿kafka网络模型与RocketMQ网络模型进行比较,到时候你会发现,它们虽然实现不一样,但是都是使用reactor模型,1个线程负责连接,3个线程负责处理read ,write事件,8个线程负责业务逻辑的处理。
接下来我们看下这个namesrv是怎样处理broker注册请求的。

2.namesrv处理注册请求

我们从DefaultRequestProcessor 的processRequest开始
在这里插入图片描述
这里就是做了一个版本的兼容,从我上面的截图也能看出来。
我们这里就看下最新的版本registerBrokerWithFilterServer方法(直接看下核心方法)
在这里插入图片描述
调用RouteInfoManager组件的registerBroker方法来处理broker的注册请求。
在看registerBroker方法之前,我们要看下RouteInfoManager组件定义的一堆集合都是代表什么东西
在这里插入图片描述
可以看到有 集群信息表,topic信息表,broker信息表,broker存活信息表,broker过滤器表
接下来我们再来看下registerBroker 方法。

1.集群信息维护
在这里插入图片描述
上来一个读写锁的写锁,很有学习意义,这也是上面我为什么将读写锁定义截图出来。
从集群表中集群对应的broker set集合,如果不存在就创建set集合,最后将该broker 添加到这个set集合中。

2.broker地址信息表维护
在这里插入图片描述
先根据broker name 从broker地址信息表中获取对应的broker信息。如果不存在就创建,标记是第一次注册,并保存到broker 地址信息表中,这个brokerData中其实有
在这里插入图片描述
因为RocketMQ是master/slave架构,他们的broker name 是一样的,然后通过brokerId区分哪个是master,哪些是slave,他这里就是拿到同一个broker name下的所有broker的地址,然后进行遍历比对,找出那种地址与该需要注册的地址相等,然后brokerId不相等的。
最后是将注册的broker addr put进去,得到一个老的addr,如果老的addr不是空,说明不是第一次注册。
3.topic配置信息表的维护
在这里插入图片描述
判断该broker是master角色,版本发生变化或者是第一次注册,就会更新namesrv维护的topic信息表。我们看下这个createAndUpdateQueueData 方法是怎样创建QueueData的。
在这里插入图片描述
其实就是根据topic获取对应的QueueData集合,因为一个topic可以分布在多个broker 上面,然后这里使用list存储的,如果topic对应的队列不存在,就创建相应的list集合,然后put到topicQueue表中,如果存在了就进行遍历,看看之前有没有存在,如果之前设置过然后数据也没发生变化就不用操作,如果发生了变化,移除,重新添加。
4.broker 存活信息表维护
在这里插入图片描述
就是创建brokerLiveInfo,然后key是broker 地址,value就是brokerLiveInfo对象,最后put进去,返回值为空的话,说明之前没有设置过,就打印日志。
5.过滤器表的维护
在这里插入图片描述
这里就不用说了,就是map的操作,如果传过来的list是空的话,说明已经没有过滤器了,就将之前维护的移除掉,否则重新put下。

接下来就是针对slave角色的,就是将它对应master的一些信息带回去,好进行ha同步
在这里插入图片描述
可以看到是将master的ha地址与master的地址带回去了。

总结

好了,这里我们broker 向namesrv注册与namesrv处理broker注册请求信息源码分析就完事了,我们在这里看到namesrv这几个map其实就是namesrv最核心的功能,它主要就是维护这些东西。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

$码出未来

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值