RocketMQ观后感--NameServer

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_27529917/article/details/79871052

先看NameServer在RocketMQ架构中的功能图:
这里写图片描述

NameServer,很多时候称为命名发现服务,其在RocketMQ中起着中转承接的作用,是一个无状态的服务,多个NameServer之间不通信。任何Producer,Consumer,Broker与所有NameServer通信,向NameServer请求或者发送数据。而且都是单向的,Producer和Consumer请求数据,Broker发送数据。正是因为这种单向的通信,RocketMQ水平扩容变得很容易。

下面我将按照Broker,Producer,Consumer的顺序来说明NameServer与他们之间的通信和发挥的作用。

NameServer与Broker间的通信和其发挥的作用:

  1. 在NameServer启动后,启动Broker。Broker在启动时会加载配置中的topic信息。加载当前Broker上的所有topic信息:topic名称;topic的Queue权限,可读,可写,可继承等等;Queue的个数。然后将这些数据传输到NameServer,美其名曰registerBroker。
  2. NameServer与Broker间维持着一个SocketChannel,长连接,Broker每隔30S向其配置的所有的NameServer执行registerBroker工作,这就是Broker和NameServer间的心跳。
  3. NameServer在接受到Broker传递的心跳信息时,若这次心跳是其第一次心跳,那么创建BrokerData,创建BrokerLiveInfo,保存其dataVersion和lastUpdateTimestamp;如果不是第一次,那么更新其lastUpdateTimestamp和dataVersion。
  4. 如果这个Broker是Master,且这次心跳信息是其第一次心跳,那么会创建当前Broker的QueueData。如果不是第一次心跳,但当前Broker的dataVersion与NameServer上保存的不一致(当Broker上新增加了topic时会更新dataVersion,dataVersion主要用当前时间戳表示),此时会用当前心跳的数据覆盖之前注册的数据。
  5. 如果当前Broker是Slave,那么将Master的brokerAddr放入心跳注册结果中,返回给Slave,这样Slave就能与Master间进行数据传输。
  6. NameServer维护着与其他组件的SocketChannel对象,针对所有组件(Broker和Client)的长连接注册了ChannelEventListener,监听此SocketChannel的连接事件。当某个SocketChannel出现异常或断开时(注意是长连接断开而不是心跳停止!),会循环遍历所有Broker的长连接,如果发现断开长连接是属于某个Broker的,那么清除此Broker的BrokerData和QueueData,如果不属于Broker,则什么都不做。这样当Client(Producer,Consumer)下次请求指定topic的TopicRouteData时,就不会包含此Broker的的数据了,也就是MessageQueue上不再包含此Broker上的Queue。
  7. 因为ChannelEventListener的连接事件处理里只对Broker做相应处理,没有涉及到Client。所以在Broker宕机或者增加时,不会实时通知Client,Client最晚需要30S时间才能感知到这种变化,因为Client更新TopicRouteData的间隔是30S。
  8. NameServer每隔30S对所有Broker的长连接进行扫描,当发现其lastUpdateTimestamp距离当前时间超过2m时,断开长连接,清空相应数据。

下面讲Producer和Consumer与NameServer间的通信:

  1. Producer在发送消息时,首先根据消息的topic查看自身是否含有此topic相应的MessageQueue( 正常情况下第一次发送时是没有的 )。当没有MessageQueue时,会从NameServer处请求指定topic的TopicRouteData,也就是List< BrokerData>和 List< QueueData>。然后根据QueueData里的writeQueueNums和BrokerData里的topic, HashMap< brokerId , broker address > 生成MessageQueue,MessageQueue的id从0开始,依次递增。注意如果BrokerData里不含有Master的Adress,那么其对应的QueueData将会被废弃,因为只有Master才能写入消息。
  2. 生成MessageQueue后,会将此topic存在生产者客户端,客户端每隔30S向NameServer请求此topic的TopicRouteData,生成MessageQueue,覆盖上次更新的值。
  3. Consumer在启动之前就需要指定订阅的topic,因此其在启动时就会想NameServer请求相应topic的TopicRouteData,同样的形式生成MessageQueue,但和Producer不同的是,Consumer可以从Slave处拉取消息,所以不会过滤Master宕机的Broker数据。
  4. Consumer客户端也每隔30S从NameServer处更新当前topic的数据,覆盖上次的值。

以上就是NameServer与各个组件间的通信机制及其发挥的作用。

猜你喜欢

转载自blog.csdn.net/qq_27529917/article/details/79871052