RocketMQ源码 — 二、 NameServer

NameServer

作用:Producer和Consumer获取Broker的地址
目的:解耦Broker和Producer、Consumer
原理:使用netty作为通信工具,监听指定端口,如果是broker注册,将broker的信息保存在内存中并保存到文件中,producer和consumer获取broker地址的请求

RocketMQ包含的组件

  • NameServer:单点,供Producer和Consumer获取Broker地址
  • Producer:产生并发送消息
  • Consumer:接受并消费消息
  • Broker:消息暂存,消息转发

NamesrvController包含的组件

  • namesrvConfig:nameServer的配置
  • nettyServerConfig:NameServer的netty配置
  • remotingServer:NameServer 的netty服务器
  • scheduledExecutorService:routeInfoManager和kvCOnfigManager使用的定时线程池
  • remotingExecutor:netty使用的线程池
  • brokerHosekeppingService:
  • kvConfigManager:kv配置管理
  • routeInfoManager:包含broker的ip和对应的队列信息,说明producer可以往哪一个broker发送消息,consumer从哪一个broker pull消息

NameServer启动

NamesrvStartup.main0

  1. NettySystemConfig配置
  2. 解析命令行参数,NettyServerConfig配置
  3. logback配置
  4. NamesrvController初始化,initialize
  5. 注册shutdown钩子
  6. NamesrvController.start

NamesrvController.initialize

  1. KVConfigManager.load加载原来的key-value文件到内存中
  2. 初始化NettyRemotingServer
  3. 注册requestProcessor,默认为DefaultRequestProcessor,用来处理netty接收到的信息
  4. 启动定时线程,每隔10s判断broker是否依然存活
  5. 启动定时线程,每隔10min打印出所有k-v

NamesrvController.start

启动netty server,使用NettyServerHandler进行read和write,最终调用到DefaultRequestProcessor.processRequest

NameServer处理信息

netty收到的所有消息都是DefaultRequestProcessor.processRequest处理的,根据不同的RequestCode执行不同的操作

public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) throws RemotingCommandException {
    if (log.isDebugEnabled()) {
        log.debug("receive request, {} {} {}",//
                request.getCode(), //
                RemotingHelper.parseChannelRemoteAddr(ctx.channel()), //
                request);
    }

    switch (request.getCode()) {
        case RequestCode.PUT_KV_CONFIG:
            return this.putKVConfig(ctx, request);
        case RequestCode.GET_KV_CONFIG:
            return this.getKVConfig(ctx, request);
        case RequestCode.DELETE_KV_CONFIG:
            return this.deleteKVConfig(ctx, request);
        case RequestCode.REGISTER_BROKER:	// 注册borker信息
            Version brokerVersion = MQVersion.value2Version(request.getVersion());
            if (brokerVersion.ordinal() >= MQVersion.Version.V3_0_11.ordinal()) {
                return this.registerBrokerWithFilterServer(ctx, request);
            }
            else {
                return this.registerBroker(ctx, request);
            }
        case RequestCode.UNREGISTER_BROKER:		// 取消注册broker
            return this.unregisterBroker(ctx, request);
        case RequestCode.GET_ROUTEINTO_BY_TOPIC:
            return this.getRouteInfoByTopic(ctx, request);		// 根据topic获取路由信息,在producer发送消息和consumer在pull消息的时候的时候会从nameServer 中获取
        case RequestCode.GET_BROKER_CLUSTER_INFO:
            return this.getBrokerClusterInfo(ctx, request);
        case RequestCode.WIPE_WRITE_PERM_OF_BROKER:
            return this.wipeWritePermOfBroker(ctx, request);
        case RequestCode.GET_ALL_TOPIC_LIST_FROM_NAMESERVER:
            return getAllTopicListFromNameserver(ctx, request);
        case RequestCode.DELETE_TOPIC_IN_NAMESRV:
            return deleteTopicInNamesrv(ctx, request);
        case RequestCode.GET_KVLIST_BY_NAMESPACE:
            return this.getKVListByNamespace(ctx, request);
        case RequestCode.GET_TOPICS_BY_CLUSTER:
            return this.getTopicsByCluster(ctx, request);
        case RequestCode.GET_SYSTEM_TOPIC_LIST_FROM_NS:
            return this.getSystemTopicListFromNs(ctx, request);
        case RequestCode.GET_UNIT_TOPIC_LIST:
            return this.getUnitTopicList(ctx, request);
        case RequestCode.GET_HAS_UNIT_SUB_TOPIC_LIST:
            return this.getHasUnitSubTopicList(ctx, request);
        case RequestCode.GET_HAS_UNIT_SUB_UNUNIT_TOPIC_LIST:
            return this.getHasUnitSubUnUnitTopicList(ctx, request);
        default:
            break;
    }
    return null;
}

这里主要看注册broker,依次调用DefaultRequestProcessor.registerBroker->RouteInfoManager.registerBroker;
进行的主要操作是解析request,依次填充以下集合,供producer和consumer获取

// 某一个topic对应的逻辑队列
private final HashMap<String/* topic */, List<QueueData>> topicQueueTable;
// 每个broker 对应的信息
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对应的filter
private final HashMap<String/* brokerAddr */, List<String>/* Filter Server */> filterServerTable;
posted @ 2017-01-15 17:04  lacker  阅读(3667)  评论(0编辑  收藏  举报