序言

在来阿里实习之前,就对消息队列非常感兴趣,当时就翻看了RocketMQ的使用指南并在本地搭建环境跑了些demo。如今项目压力不太大,就准备趁着实习期间来细看RocketMQ的原理和源码实现.

NameServer作用

nameServer顾名思义,在系统中肯定是做命名服务,服务治理方面的工作,功能应该是和zookeeper差不多,据我了解,RocketMq的早期版本确实是使用的zookeeper,后来改为了自己实现的nameserver。

现在来看一下nameServer在RocketMQ中的两个主要作用:

  • NameServer维护了一份Broker的地址列表和,broker在启动的时候会去NameServer进行注册,会维护Broker的存活状态.

  • NameServer维护了一份Topic和Topic对应队列的地址列表,broker每次发送心跳过来的时候都会把Topic信息带上.

NameServer中的重要类结构


NamesrvStartUp:NameServer启动类
NamesrvController:NameServer控制类,管控NameServer的启动、初始化、停止等生命周期
RouteInfoManager:这个类非常重要,存放了topic队列信息,broker地址列表等一系列重要数据结构,并提供了对应的数据变更接口。
DefaultRequestProcessosr:负责处理所broker发过来的所有网络消息,封装了对netty包的处理和部分对nameServer存储的数据查询和删除。

NameServer中的数据结构


private final HashMap<String/* topic */, List<QueueData>> topicQueueTable;//topic队列表,存储了每个topic包含的队列数据


private final HashMap<String/* brokerName */, BrokerData> brokerAddrTable; //broker地址表


private final HashMap<String/* clusterName */, Set<String/* brokerName */>> clusterAddrTable; //集群主备信息表


private final HashMap<String/* brokerAddr */, BrokerLiveInfo> brokerLiveTable; //broker存活状态信息表,
    其中的BrokerLiveInfo存储了broker的版本号,channel,和最近心跳时间等信息

private final HashMap<String/* brokerAddr */, List<String>/* Filter Server */> filterServerTable; 
//记录了每个broker的filter信息.

private final HashMap<String/* Namespace */, HashMap<String/* Key */, String/* Value */>> configTable
 //根据namespace配置区分的config表

上面的几个重要的队列数据之所以没有用并发数据结构,是因为在对这些数据的读写中都使用了读写锁进行并发控制。

BrokerData 中有

private HashMap Long/* brokerId /, String/ broker address */> brokerAddrs;

这个数据结构保存了broker的具体地址,brokerId = 0 时是master broker

nameServer启动流程

下面是nameServer启动的时序图

本文主要讲解下broker注册和心跳包检测两个场景的代码,比较有代表性.

  • broker注册

首先是在DefaultRequestProcessor中处理registerBroker请求:

然后是调用RouteInfoManager中的registerBorker方法,这个方法是真正的逻辑操作:



  • broker心跳定期扫描

心跳扫描首先是NamesrvController的初始化过程中起的线程:

删除长连接的channel

获取要删除的地址


删除对应的表信息:


可以看到核心操作都是维护之前的数据结构

总结

1、为什么需要nameServer而不是直接用zookeeper

据我了解,RocketMQ2.0版本都是用的zookeeper做服务注册,但其实每个broker存储的topic都是只存自己的一部分,并不需要维护全局的topic信息,所以不需要zookeeper这么重的组件来做.

所以任何的组件引用都必须适应使用场景

2、nameServer主要的功能和原理总结?

namerServer上维护了很多broker和topic等信息,通过netty和broker进行长连接来保持和broker的通信,同时会提供心跳检测、数据更新查询等常规服务。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐