RocketMQ探索-broker注册到namesrv中

根据前面介绍,可以看到broker在启动的时候要向namesrv注册自己,这里我们就来看看broker怎么向namesrv注册自己。

在BrokerController的start()中会向注册namesrv注册自己,并启动定时注册Broker到Name Server的任务。

  • start()方法中的注册方法:

       // 启动时,强制注册
        this.registerBrokerAll(true, false);

        // 定时注册Broker到Name Server
        this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {

            @Override
            public void run() {
                try {
                    BrokerController.this.registerBrokerAll(true, false);
                } catch (Throwable e) {
                    log.error("registerBrokerAll Exception", e);
                }
            }
        }, 1000 * 10, 1000 * 30, TimeUnit.MILLISECONDS);

  • 接着看registerBrokerAll方法:
/**
 *  定时注册Broker到Name Server
 * @param checkOrderConfig
 * @param oneway
 */
public synchronized void registerBrokerAll(final boolean checkOrderConfig, boolean oneway) {
    TopicConfigSerializeWrapper topicConfigWrapper = this.getTopicConfigManager().buildTopicConfigSerializeWrapper();

    //每次注册的时候都会 同步Broker最新的读写权限到每一个topic中(TopicConfig对象中),放到TopicConfigTable中
    //注册的时候要携带这些信息
    if (!PermName.isWriteable(this.getBrokerConfig().getBrokerPermission())
            || !PermName.isReadable(this.getBrokerConfig().getBrokerPermission())) {
        ConcurrentHashMap<String, TopicConfig> topicConfigTable = new ConcurrentHashMap<String, TopicConfig>();
        for (TopicConfig topicConfig : topicConfigWrapper.getTopicConfigTable().values()) {
            TopicConfig tmp =
                    new TopicConfig(topicConfig.getTopicName(), topicConfig.getReadQueueNums(), topicConfig.getWriteQueueNums(),
                            this.brokerConfig.getBrokerPermission());
            topicConfigTable.put(topicConfig.getTopicName(), tmp);
        }
        topicConfigWrapper.setTopicConfigTable(topicConfigTable);
    }

    /**
     * 注册时携带的信息是:
     * cluster name,broker 地址,broker name,broker id //0为master 1为slave,HA地址,即slave可以通过该地址与master进行数据同步
     * topic信息 包含topic name,read queue num, write queue num, permission
     */
    RegisterBrokerResult registerBrokerResult = this.brokerOuterAPI.registerBrokerAll(//
            this.brokerConfig.getBrokerClusterName(), //
            this.getBrokerAddr(), //
            this.brokerConfig.getBrokerName(), //
            this.brokerConfig.getBrokerId(), //
            this.getHAServerAddr(), //
            topicConfigWrapper,//
            this.filterServerManager.buildNewFilterServerList(),//
            oneway,//
            this.brokerConfig.getRegisterBrokerTimeoutMills());

    if (registerBrokerResult != null) {
        if (this.updateMasterHAServerAddrPeriodically && registerBrokerResult.getHaServerAddr() != null) {
            this.messageStore.updateHaMasterAddress(registerBrokerResult.getHaServerAddr());
        }

        this.slaveSynchronize.setMasterAddr(registerBrokerResult.getMasterAddr());

        // 检查 topic config 的顺序消息配置
        if (checkOrderConfig) {
            this.getTopicConfigManager().updateOrderTopicConfig(registerBrokerResult.getKvTable());
        }
    }
}
  • 接着看BrokerOuterAPI类的registerBrokerAll方法
/**
 * 注册Broker到Name Server
 * @param clusterName
 * @param brokerAddr
 * @param brokerName
 * @param brokerId
 * @param haServerAddr
 * @param topicConfigWrapper
 * @param filterServerList
 * @param oneway
 * @param timeoutMills
 * @return
 */
public RegisterBrokerResult registerBrokerAll(//
                                              final String clusterName, // 1
                                              final String brokerAddr, // 2
                                              final String brokerName, // 3
                                              final long brokerId, // 4
                                              final String haServerAddr, // 5
                                              final TopicConfigSerializeWrapper topicConfigWrapper, // 6
                                              final List<String> filterServerList, // 7
                                              final boolean oneway,// 8
                                              final int timeoutMills// 9
) {
    RegisterBrokerResult registerBrokerResult = null;

    //获取namesrv的地址信息列表
    List<String> nameServerAddressList = this.remotingClient.getNameServerAddressList();
    if (nameServerAddressList != null) {
        for (String namesrvAddr : nameServerAddressList) { //循环namesrv的信息列表把broker注册到每一个namesrv中
            try {
                RegisterBrokerResult result = this.registerBroker(namesrvAddr, clusterName, brokerAddr, brokerName, brokerId,
                        haServerAddr, topicConfigWrapper, filterServerList, oneway, timeoutMills);
                if (result != null) {
                    registerBrokerResult = result;
                }

                log.info("register broker to name server {} OK", namesrvAddr);
            } catch (Exception e) {
                log.warn("registerBroker Exception, " + namesrvAddr, e);
            }
        }
    }

    return registerBrokerResult;
}
  • 接着看BrokerOuterAPI类的registerBroker方法
private RegisterBrokerResult registerBroker(//
                                            final String namesrvAddr, //
                                            final String clusterName, // 1
                                            final String brokerAddr, // 2
                                            final String brokerName, // 3
                                            final long brokerId, // 4
                                            final String haServerAddr, // 5
                                            final TopicConfigSerializeWrapper topicConfigWrapper, // 6
                                            final List<String> filterServerList, // 7
                                            final boolean oneway,// 8
                                            final int timeoutMills// 9
) throws RemotingCommandException, MQBrokerException, RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException,
        InterruptedException {
    RegisterBrokerRequestHeader requestHeader = new RegisterBrokerRequestHeader();
    requestHeader.setBrokerAddr(brokerAddr);
    requestHeader.setBrokerId(brokerId);
    requestHeader.setBrokerName(brokerName);
    requestHeader.setClusterName(clusterName);
    requestHeader.setHaServerAddr(haServerAddr);
    //这里利用命令模式对请求的信息进行封装,告诉接收请求的service端,该请求的目的是什么(比如这里的REGISTER_BROKER,告诉service端该请求是注册broker)
    RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.REGISTER_BROKER, requestHeader);

    RegisterBrokerBody requestBody = new RegisterBrokerBody();
    requestBody.setTopicConfigSerializeWrapper(topicConfigWrapper);
    requestBody.setFilterServerList(filterServerList);
    request.setBody(requestBody.encode());

    //以上就完成了向namesrv注册broker的请求头和请求体

    if (oneway) {
        try {
            this.remotingClient.invokeOneway(namesrvAddr, request, timeoutMills);
        } catch (RemotingTooMuchRequestException e) {
        }
        return null;
    }

    RemotingCommand response = this.remotingClient.invokeSync(namesrvAddr, request, timeoutMills);
    assert response != null;
    switch (response.getCode()) {
        case ResponseCode.SUCCESS: {
            RegisterBrokerResponseHeader responseHeader =
                    (RegisterBrokerResponseHeader) response.decodeCommandCustomHeader(RegisterBrokerResponseHeader.class);
            RegisterBrokerResult result = new RegisterBrokerResult();
            result.setMasterAddr(responseHeader.getMasterAddr());
            result.setHaServerAddr(responseHeader.getHaServerAddr());
            result.setHaServerAddr(responseHeader.getHaServerAddr());
            if (response.getBody() != null) {
                result.setKvTable(KVTable.decode(response.getBody(), KVTable.class));
            }
            return result;
        }
        default:
            break;
    }

    throw new MQBrokerException(response.getCode(), response.getRemark());
}
RemotingCommand response = this.remotingClient.invokeSync(namesrvAddr, request, timeoutMills);

调用invokeSync方法进行broker的注册。通信后面专门看看

大体的说明都在写在了方法的注释上面了。

转载于:https://my.oschina.net/u/3134950/blog/1377710

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值