中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

RocketMQ 源碼學(xué)習(xí) 2 : Namesrv

2018-07-02    來源:importnew

容器云強勢上線!快速搭建集群,上萬Linux鏡像隨意使用

1. Namesrv 簡介

Namesrv 可以理解為一個注冊中心, 整個Namesrv的代碼非常簡單,主要包含兩塊功能:

  • 管理一些 KV 的配置
  • 管理一些 Topic、Broker的注冊信息

2. Namesrv 啟動過程

啟動過程主要涉及 NamesrvStartup/NamesrvController 兩個類, NamesrvStartup 負責(zé)解析命令行的一些參數(shù)到各種 Config 對象中(NamesrvConfig/NettyServerConfig等),如果命令行參數(shù)中帶有配置文件的路徑,也會從配置文件中讀取配置到各種 Config 對象中,然后初始化 NamesrvController,配置shutdownHook, 啟動 NamesrvController。 NamesrvController 會去初始化和啟動各個組件,主要是:

  • 創(chuàng)建NettyServer,注冊 requestProcessor,用于處理不同的網(wǎng)絡(luò)請求
  • 啟動 NettyServer
  • 啟動各種 scheduled task.

不僅僅 Namesrv 是這樣,其他模塊在啟動過程中也都是 startup/controller/config 一起完成這樣的套路。

3. Namesrv 主要組件

  • Processor 線程池,nettyServer 接收到請求后,封裝成任務(wù)提交到該線程池。
    remoting 模塊維護了這樣一個 processorTable:
HashMap<Integer/* request code */, Pair<NettyRequestProcessor, ExecutorService>> processorTable

一個 processor 可以處理多個 request code, 多個 processor 也可以共用一個線程池。對于 Namesrv, 只有一個 processor 線程池,給兩個 Processor 共享。

  • DefaultRequestProcessor(Namesrv 還有一個 ClusterTestRequestProcessor 繼承了該 Processor,在 clusterTest enable的情* 況下使用它來 getRouteInfoByTopic),用來處理 namesrv 接收到的所有 RequestCode, Processor 內(nèi)部會根據(jù)不同的RequestCode 調(diào)用不同的方法。
  • KVConfigManager, 維護了一些KV方式的配置數(shù)據(jù),可以根據(jù)請求,執(zhí)行添加、刪除、查詢等操作
  • RouteInfoManager, 維護了topic/broker/cluster/filter這些東西的路由信息,同樣支持增刪改查的操作
  • schedued 線程,按一定的頻率做兩個事情,掃描不活躍的broker;打印所有KV配置信息

4. 以broker注冊為例看下Namesrv的工作過程

  1. DefaultRequestProcessor 處理來自 NettyServer的 [RemotingCommand] request, 如果 request.getCode 是 RequestCode.REGISTER_BROKER, 就去注冊。這里會根據(jù)request.version來判斷,從V3_0_11 開始支持了FilterServer。
  2. 從 request 解碼得到 RegisterBrokerRequestHeader, 包含以下字段:
    • brokerName, // 默認是BrokerConfig里的獲得的locakHostName
    • brokerAddr, //brokerConfig.getBrokerIP1() + “:” + nettyServerConfig.getListenPort()
    • clusterName, //默認是BrokerConfig的”DefaultCluster”
    • haServerAddr, //brokerConfig.getBrokerIP2() + “:” + messageStoreConfig.getHaListenPort()
    • brokerId, //如果是MASTER,就是MixAll.MASTER_ID(也就0),否則就是其他
  3. 從 request.body 解碼得到 RegisterBrokerBody, RegisterBrokerBody 包含以下內(nèi)容,用JSON的方式來描述吧:
    {
      "topicConfigSerializeWrapper": {
          "topicConfigTable":{
             "topic_xxx":{
               "defaultReadQueueNums":"16",
              "defaultWriteQueueNums":"16",
              "topicName":"xxx",
              "readQueueNums":"",
              "writeQueueNums":"",
              "perm":"",
              "topicFilterType":"",
              "topicSysFlag":"",
              "order":""
             },
          },
          "dataVersion":{
             "timestamp":"xxxx",
             "counter":"xxxx"
          }
       },
      "filterServerList":[
         "",//filterServerAddr
      ]
    }
  4. 在 clusterAddrTable 中新增一條記錄
  5. 在 brokerAddrTable 中新增一條記錄,這里會構(gòu)建一個BrokerData
    {
      "cluster":"xxx",
      "brokerName":"xxx",
      "brokerAddrs":{
         "brokerId_xx":"broker address xxx"
       }
    }
  6. 如果是第一次注冊或者topicConfig發(fā)生了變更,會去更新topicQueueTable
  7. 在brokerLiveTable新增該broker
  8. 在filterServerTable新增這些filterServer的地址列表

5.其他

以上內(nèi)容看下來,namesrv 是一個無狀態(tài)的應(yīng)用,可以水平任意擴展。每一個 broker 都會和所有的 namesrv 保持長連接(有個scheduled task會按一定頻率給所有namesrv做register broker的操作),所以 namesrv 之間沒有主從關(guān)系,也不需要復(fù)制數(shù)據(jù)。client(producer/consumer) 隨機選一個 namesrv 連接。client 中的 namesrv 地址列表是怎么來的呢,有兩種方式:

  1. 通過命令行或配置文件在啟動的時候獲得的
  2. 通過 Scheduled task,按一定的頻率從一個 web 服務(wù) fetch的(web服務(wù)可以自建),如果有變更,就更新這個 namesrv 地址列表。
    client 選擇 namesrv的過程如下, index遞增取模,然并不是每次都這么干,取到后會緩存起來。
if (addrList != null && !addrList.isEmpty()) {
    for (int i = 0; i < addrList.size(); i++) {
        int index = this.namesrvIndex.incrementAndGet();
        index = Math.abs(index);
        index = index % addrList.size();
        String newAddr = addrList.get(index);
        this.namesrvAddrChoosed.set(newAddr);
        Channel channelNew = this.createChannel(newAddr);
        if (channelNew != null)
            return channelNew;
    }
}

看到這里我產(chǎn)生了疑問,那豈不是每個 client 啟動的時候都取的是第一個 namesrv,它不會壓力很大嗎,后來發(fā)現(xiàn) namesrvIndex 的初始值是隨機的。

以上所有扯淡都是基于源碼?https://github.com/apache/incubator-rocketmq?(tag:rocketmq-all-4.1.0-incubating)所貼代碼有所刪減。

標(biāo)簽: 代碼 網(wǎng)絡(luò)

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請與原作者聯(lián)系。

上一篇:MySQL 狀態(tài)變量 Aborted_connects 與 Aborted_clients 淺析

下一篇:Git 內(nèi)部原理之 Git 對象哈希