RocketMQ之NameServer
1. NameServer架构设计
为了避免消息服务器的单点故障导致的整个系统瘫痪,通常会部署多台消息服务器共同承担消息的存储。那消息生产者如何知道消息要发往哪台消息服务器呢?如果一台消息服务器宕机了,那么生产者如何在不重启服务的情况下感知呢?
NameServer就是为了解决上述问题而设计的。

RocketMQ整体工作流程:
1. Broker消息服务器在启动时向所有NameServer注册
2. 消息生产者在发送消息之前先从NameServer获取Broker服务器地址列表,然后根据负载算法从列表中选择一台消息服务器进行消息发送。
3. NameServer与每台Broker服务器保持长连接,并间隔30s检测Broker是否存活。如果检测到Broker宕机,则从路由注册表中将其移除。
4. NameServer本身的高可用可通过部署多台NameServer服务器来实现,但彼此之间互不通信。
2. NameServer启动流程
1. 加载配置文件
1. -c configFile通过-c命令指定配置文件的路径
2. 使用"-- 属性名 属性值"
2. 根据启动属性创建NamesrvController实例,并初始化该实例。
加载KV配置,创建NettyServer网络处理对象,然后开启两个定时任务,在RocketMQ中此类定时任务统称为心跳检测。
定时任务1:NameServer每隔10s扫描一次Broker,移除处于不激活状态的Broker
定时任务2:NameServer每隔10分钟打印一次KV配置
3. 注册JVM钩子函数并启动服务器,以便监听Broker,消息生产者的网络请求
3. NameServer路由注册,故障剔除
1. NameServer的主要作用
为消息生产者和消息消费者提供关于主题Topic的路由信息,NameServer需要存储路由的基础信息,还要管理Broker节点,包括路由注册,路由删除等功能。
2. 路由元消息
topicQueueTable Topic消息队列路由信息,消息发送时根据路由表进行负载均衡
brokerAddrTable Broker基础信息,包含brokerName,所属集群名称,主备Broker地址
clusterAddrTable Broker集群信息,存储集群中所有Broker名称
brokerLiveTable Broker状态信息。NameServer每次收到心跳包时会替换该信息
filterServerTable Broker上的FilterServer列表,用于类模式消息过滤
3. 路由注册
RocketMQ路由注册是通过Broker与NameServer的心跳功能实现的。
Broker启动时向集群中所有的NameServer发送心跳语句,每隔30s向集群中所有NameServer发送心跳包,NameServer收到Broker心跳包时会更新brokerLiveTable缓存中BrokerLiveInfo的lastUpdateTimestamp,然后NameServer每隔10s扫描BrokerLiveInfo,如果连续120s没有收到心跳包,NameServer将移除该Broker的路由信息同时关闭Sockert连接。
1. Broker发送心跳包
首先封装请求包头
brokerAddr broker地址
brokerId 0为master;大于0为slave
brokerName broker名称
clusterName 集群名称
haServerAddr master地址,初次请求为空
requestBody 请求体
2. NameServer处理心跳包
1. 路由注册需要加写锁,防止并发修改RouteInfoManager中的路由表。首先判断Broker所属集群是否存在,如果不存在,则创建,然后将broker名加入到集群Broker集合中。
2. 维护BrokerData信息,首先从brokerAddrTable根据BrokerName尝试获取Broker信息,如果不存在,则新建BrokerData并放入到brokerAddrTable,registerFirst设置为true;如果存在,直接替换原先的,registerFirst设置为false,表示非第一次注册。
3. 如果Broker为Master,并且Broker Topic配置信息发生变化或者是初次注册,则需要创建或更新Topic路由元数据,填充topicQueueTable。
4. 更新BrokerLiveInfo,存活Broker信息表,BrokeLiveInfo是执行路由删除的重要依据。
5. 注册Broker的过滤器Server地址列表,一个Broker上会关联多个FilterServer消息过滤服务器;如果此Broker为从节点,则需要查找该Broker的Master的节点信息,并更新对应的masterAddr属性。
4. 路由删除
Broker启动时向集群中所有的NameServer发送心跳语句,每隔30s向集群中所有NameServer发送心跳包,NameServer收到Broker心跳包时会更新brokerLiveTable缓存中BrokerLiveInfo的lastUpdateTimestamp,然后NameServer每隔10s扫描BrokerLiveInfo,如果连续120s没有收到心跳包,NameServer将移除该Broker的路由信息同时关闭Sockert连接。
1. RocketMQ有两个触发点来触发路由删除
1. NameServer定时扫描brokerLiveTable检测上次心跳包与当前系统时间的时间差,如果时间戳大于120s,则需要移除该Broker信息
2. Broker在正常被关闭的情况下,会执行unregisterBroker指令
2. 删除过程
1. 申请写锁,根据brokerAddress从brokerLiveTable,filterServerTable移除
2. 维护brokerAddrTable.找到具体的Broker,从BrokerData中移除,如果移除后在BrokerData中不再包含其他Broker,则在brokerAddrTable中移除该brokerName对应的条目。
3. 根据BrokerName,从clusterAddrTable中找到Broker并从集群中移除。如果移除后,集群中不包含任何Broker,则将该集群从clusterAddrTable中移除。
4. 根据brokerName,遍历所有主题的队列,如果队列中包含了当前broker的队列,则删除,如果topic只包含待删除broker队列的话,从路由表中删除该topic.
5. 释放锁,完成路由删除
5. 路由发现
RocketMQ路由发现是非实时的,当Topic路由出现变化后,NameServer不主动推送给客户端,而是由客户端定时拉取主题最新的路由。
1. 具体过程
1. 调用RouterInfoManager的方法,从路由表topicQueueTable,brokerAddrTable,filterServerTable中分别填充TopicRouteData中的List<QueueData>,List<BrokerData>和filterServer地址表
2. 如果找到主题对应的路由信息并且该主题为顺序消息,则从NameServer KVconfig中获取关于顺序消息相关的配置填充路由信息
4. NameServer工作图


浙公网安备 33010602011771号