Rocketmq5.0客户端如何发现Namserver地址源码分析
这里是weihubeats,觉得文章不错可以关注公众号小奏技术,文章首发。拒绝营销号,拒绝标题党
源码版本
- rocketmq:release-5.0.0
生产者一般使用
DefaultMQProducer producer = new DefaultMQProducer(PRODUCER_GROUP);
producer.setNamesrvAddr(DEFAULT_NAMESRVADDR);
producer.start();
如何设置NameServer地址
以下方式由高到底
- 通过java启动参数设置,比如通过设置环境变量
System.setProperty(MixAll.NAMESRV_ADDR_PROPERTY, "127.0.0.1:9876");
- 通过设置服务器环境变量(Linux)
-n 127.0.0.1:9876
- 通过代码设置,比如
producer.setNamesrvAddr(DEFAULT_NAMESRVADDR);
- 通过HTTP服务来设置,当上面都没有设置,会向一个HTTP地址发送请求来获取NameServer地址,默认的URL是jmenv.tbsite.net:8080/rocketmq/ns… (淘宝的测试地址),
我们可以通过设置系统参数
rocketmq.namesrv.domain
来覆盖jmenv.tbsite.net
的值, 通过设置rocketmq.namesrv.domain.subgroup
参数来覆盖nsaddr
的值
可以看到4通过设置HTTP服务
获取NameServer
的地址是最麻烦的,相当于自己还要出一个获取获取NameServer
的接口,但是他是唯一支持动态增加NameServer
,不用重启其他组件的方式
源码分析
我们现在通过源码方式分析上面的几种设置方式
这里的
ClientConfig
实际就是DefaultMQProducer
,也就是我们发送消息的第一步,创建一个DefaultMQProducer
System.setProperty(MixAll.NAMESRV_ADDR_PROPERTY, "10.10.10.1:9999");
DefaultMQProducer producer = new DefaultMQProducer(PRODUCER_GROUP);
通过DefaultMQProducer
的构造方法我们可以看到namesrvAddr
的默认值是通过NameServerAddressUtils.getNameServerAddresses()
注意这里的DefaultMQProducer
是继承了DefaultMQProducer
我们看看NameServerAddressUtils.getNameServerAddresses()
方法的具体实现
可以看到首先通过获取环境变量,其次是获取系统环境变量
这里就解释了我们的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
构造的
但是这里的clientConfig
就是DefaultMQProducer
,我们可以通过debug的方式去确认
这里可以看到就验证了我们说的通过代码设置。
我们继续向下看
发现在product
启动这里会去通过clientConfig
获取namesrvAddr
,如果我们之前的代码里面没有设置namesrvAddr
的地址,那这里就会为空,然后就通过fetchNameServerAddr
去获取namesrvAddr
的地址
进到方法fetchNameServerAddr
里面我们会发现是通过TopAddressing
类的fetchNSAddr
方法
我们看看
这里核心就是这个方法
return fetchNSAddr(true, 3000);
我们进去看看
可以看到这里通过http去获取namesrvAddr
地址,url
的获取是通过this.wsAddr;
获取的,所以我们重点看看wsAddr
如何初始化的
可以看到是通过MixAll.getWSAddr()
的方法获取的,我们看看getWSAddr
方法
阿里云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
地址
总结
这里我们通过源码的方式验证了rocketmq
product获取namesrvAddr
的几种方式,其中最推荐的还是通过HTTP服务来获取,因为可以自由扩容
转载自:https://juejin.cn/post/7207607724899745852