天天看點

Rocketmq5.0用戶端如何發現Namserver位址源碼分析

作者:是啊超ya
Rocketmq5.0用戶端如何發現Namserver位址源碼分析

源碼版本

  • rocketmq:release-5.0.0

生産者一般使用

DefaultMQProducer producer = new DefaultMQProducer(PRODUCER_GROUP);
producer.setNamesrvAddr(DEFAULT_NAMESRVADDR);
producer.start();

           

如何設定NameServer位址

以下方式由高到底

  1. 通過java啟動參數設定,比如通過設定環境變量
System.setProperty(MixAll.NAMESRV_ADDR_PROPERTY, "127.0.0.1:9876");

           
  1. 通過設定伺服器環境變量(Linux)
-n 127.0.0.1:9876

           
  1. 通過代碼設定,比如
producer.setNamesrvAddr(DEFAULT_NAMESRVADDR);

           
  1. 通過HTTP服務來設定,當上面都沒有設定,會向一個HTTP位址發送請求來擷取NameServer位址,預設的URL是http://jmenv.tbsite.net:8080/rocketmq/nsaddr (淘寶的測試位址), 我們可以通過設定系統參數rocketmq.namesrv.domain來覆寫 jmenv.tbsite.net的值, 通過設定rocketmq.namesrv.domain.subgroup參數來覆寫nsaddr的值

可以看到4通過設定HTTP服務擷取NameServer的位址是最麻煩的,相當于自己還要出一個擷取擷取NameServer的接口,但是他是唯一支援動态增加NameServer,不用重新開機其他元件的方式

源碼分析

我們現在通過源碼方式分析上面的幾種設定方式

Rocketmq5.0用戶端如何發現Namserver位址源碼分析
這裡的ClientConfig實際就是DefaultMQProducer,也就是我們發送消息的第一步,建立一個DefaultMQProducer
System.setProperty(MixAll.NAMESRV_ADDR_PROPERTY, "10.10.10.1:9999");
DefaultMQProducer producer = new DefaultMQProducer(PRODUCER_GROUP);

           

通過DefaultMQProducer的構造方法我們可以看到namesrvAddr的預設值是通過NameServerAddressUtils.getNameServerAddresses()

Rocketmq5.0用戶端如何發現Namserver位址源碼分析
Rocketmq5.0用戶端如何發現Namserver位址源碼分析

注意這裡的DefaultMQProducer是繼承了DefaultMQProducer

Rocketmq5.0用戶端如何發現Namserver位址源碼分析

我們看看NameServerAddressUtils.getNameServerAddresses()方法的具體實作

Rocketmq5.0用戶端如何發現Namserver位址源碼分析

可以看到首先通過擷取環境變量,其次是擷取系統環境變量

這裡就解釋了我們的1、2優先級。 看到了1、2的方法也很容易證明3的設定方式了,預設值是1、2,如果我們設定了就是3的設定方式 可以看到這裡的的namesrvAddr位址的擷取主要是通過clientConfig擷取的,而clientConfig的構造就是通過DefaultMQProducer構造的(前面分析的),而我們就可以通過在啟動Product的時候設定 比如

DefaultMQProducer producer = new DefaultMQProducer(PRODUCER_GROUP);
producer.setNamesrvAddr("name-server1-ip:9876;name-server2-ip:9876");

           

可以看到clientConfig就是在這裡通過clientConfig構造的

Rocketmq5.0用戶端如何發現Namserver位址源碼分析

但是這裡的clientConfig就是DefaultMQProducer,我們可以通過debug的方式去确認

Rocketmq5.0用戶端如何發現Namserver位址源碼分析

這裡可以看到就驗證了我們說的通過代碼設定。

我們繼續向下看 發現在product啟動這裡會去通過clientConfig擷取namesrvAddr,如果我們之前的代碼裡面沒有設定namesrvAddr的位址,那這裡就會為空,然後就通過fetchNameServerAddr去擷取namesrvAddr的位址

Rocketmq5.0用戶端如何發現Namserver位址源碼分析

進到方法fetchNameServerAddr裡面我們會發現是通過TopAddressing類的fetchNSAddr方法

Rocketmq5.0用戶端如何發現Namserver位址源碼分析

我們看看

Rocketmq5.0用戶端如何發現Namserver位址源碼分析

這裡核心就是這個方法

return fetchNSAddr(true, 3000);
           

我們進去看看

Rocketmq5.0用戶端如何發現Namserver位址源碼分析

可以看到這裡通過http去擷取namesrvAddr位址,url的擷取是通過this.wsAddr;擷取的,是以我們重點看看wsAddr如何初始化的

Rocketmq5.0用戶端如何發現Namserver位址源碼分析

可以看到是通過MixAll.getWSAddr()的方法擷取的,我們看看getWSAddr方法

Rocketmq5.0用戶端如何發現Namserver位址源碼分析

阿裡雲ons clinetbus直接設定的是NAMESRV_ADDR嗎

從上面我們可以确認最好的方式是通過http方式擷取namesrvAddr位址,那麼為什麼我們使用阿裡雲的ons-clinet是這種方式呢

Properties properties = new Properties();
        properties.put(PropertyKeyConst.AccessKey, aliMQAccessKey);
        properties.put(PropertyKeyConst.SecretKey, aliMQSecretKey);
        properties.put(PropertyKeyConst.NAMESRV_ADDR, domainEventNameSrv);
        return ONSFactory.createProducer(properties);

           

咋看好像是直接設定了NAMESRV_ADDR位址,其實我們随便看看源碼發現他也是設定的是wsAddr位址

Rocketmq5.0用戶端如何發現Namserver位址源碼分析

總結

這裡我們通過源碼的方式驗證了rocketmq product擷取namesrvAddr的幾種方式,其中最推薦的還是通過HTTP服務來擷取,因為可以自由擴容

繼續閱讀