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工作图   

    

 

         

posted @ 2024-01-11 14:07  奋斗史  阅读(53)  评论(0)    收藏  举报