Nacos 客户端寻址
在使用Nacos时, Nacos客户端需要配置Nacos服务器的地址,以确保客户端能连接到Nacos服务器,从而实现服务发现和注册等功能。
本文档将介绍Nacos客户端的各种寻址逻辑,以及多种不同的寻址方式的优先级;对于部分支持拓展寻址的编程语言的客户端,本文档还会介绍如何实现自定义的寻址逻辑。
1. 客户端寻址基本逻辑
Nacos的所有客户端在寻址Nacos服务端时,虽然具体的实现有所差异,但基本都遵循如下逻辑:
- 首先,Nacos客户端会根据初始化时,接受来自应用的配置,如
Properties
等信息; - 在Nacos客户端初始化过程中,会创建一个
ServerListManager(服务列表管理器)
,用于管理服务端的地址列表; - 根据传入的
Properties
配置信息,ServerListManager
会选择一个对应的ServerListProvider(服务列表提供者)
来实际获取服务端地址列表,默认情况下,Nacos客户端会提供基于server-addr配置
的PropertiesServerListProvider
,和Endpoint 地址服务器
的EndpointServerListProvider
; - 在
ServerListManager
完成ServerListProvider
的选取、初始化以及从其中获取到服务端地址列表后,Nacos客户端才会创建用于通信的GrpcClient
,并使用ServerListManager
管理的服务端地址列表来创建连接,并请求对应的Nacos Server。
不同的ServerListProvider
会导致客户端在寻找服务端地址列表时的行为有所不同,下文对不同ServerListProvider
的使用条件、行为结果、优先级等特性进行说明:
1.1. 基于配置的寻址逻辑
Nacos客户端默认提供了基于配置的ServerListProvider
,即PropertiesServerListProvider
,该ServerListProvider
会根据server-addr
配置,从配置中获取服务端地址列表,若配置中存在多个服务端地址,Nacos客户端将会使用,
和;
字符进行分割、并最终随机选择一个作为服务端地址。
若当前选择的服务端地址不可用,则Nacos客户端会按照轮询的方式,依次尝试使用其他服务端地址,当尝试所有的地址之后,会回到第一个服务端地址,继续轮询,直至找到可用的服务端地址或客户端中止。
这种寻址方式的最大优点是,Nacos客户端的配置非常简单,只需要配置server-addr
即可,无需配置额外的服务端地址列表配置;同时也无需部署额外的组件;但是,这种寻址方式相对不灵活,无法动态的修改服务端地址列表,需要修改时只能重新创建一个新的Nacos客户端使用。
使用示例:
注意:不同编程语言的配置方式可能存在差异,请根据实际情况修改。
待补充
1.2. 基于Endpoint地址服务器的寻址逻辑
Nacos客户端还提供了基于地址服务器的寻址方式,即EndpointServerListProvider
,该ServerListProvider
会根据endpoint
配置,从endpoint
所指向的地址服务器中获取服务端地址列表;
地址服务器可以是任意一个提供对应HTTP接口的服务端,例如一个nginx
,tomcat服务端
,Nacos的address模块等
等等;对应接口需要按照格式返回Nacos服务端的地址列表,格式为每行一个地址,例如:
若返回的地址没有端口,则默认端口为8848。
同样地,Nacos客户端会随机选择列表中的一个地址作为服务端地址,并使用该地址访问Nacos服务端;若该地址不可用,则Nacos客户端会按照轮询的方式,依次尝试使用其他服务端地址,当尝试所有的地址之后,会回到第一个服务端地址,继续轮询,直至找到可用的服务端地址或客户端中止。
该寻址方式的最大优点是可以动态的更新客户端所连接的服务端地址列表,无需重启客户端;但是,这种寻址方式需要额外部署一个地址服务器以提供对应的更新和获取地址列表的接口、同时可能需要配置的内容较多,适合Nacos部署规模较大的场景。
使用示例:
注意:不同编程语言的配置方式可能存在差异,请根据实际情况修改。
更多地址服务器相关配置,请参考Java SDK 配置参数-通用参数。
待补充
1.3. 不同寻址逻辑的触发优先级
当Nacos客户端启动时, 同时配置了不同的寻址逻辑,Nacos客户端会按照以下优先级进行服务端地址的获取:
- 优先使用
EndpointServerListProvider
,尝试读取endpoint
相关配置,若存在,则使用EndpointServerListProvider
获取服务端地址列表,endpoint
相关配置默认又遵循如下优先级;
- 1.1. 其中环境变量
ALIBABA_ALIWARE_ENDPOINT_URL
的优先级最高,如果存在,则使用ALIBABA_ALIWARE_ENDPOINT_URL
作为地址服务器地址; - 1.2. 其次是初始化时传入的Properties中
endpoint
配置优先,如果存在,则使用endpoint
所配置的地址作为地址服务器地址; - 1.3. 再优先是JVM参数中配置的
endpoint
配置优先,如果存在,则使用JVM中的endpoint
所配置的地址作为地址服务器地址; - 1.4. 最后是环境变量中的
endpoint
,如果存在,使用环境变量中endpoint
中配置的地址作为地址服务器地址;
- 若以上关于
EndpointServerListProvider
的配置均不存在,则使用PropertiesServerListProvider
- 1.1. 优先使用初始化时传入的Properties中
serverAddr
配置,如果存在,则使用serverAddr
配置的地址作为Nacos服务端地址列表; - 1.2. 其次是JVM参数中配置的
serverAddr
配置,如果存在,则使用JVM中的serverAddr
配置的地址作为Nacos服务端地址列表; - 1.3. 最后是环境变量中的
serverAddr
,如果存在,使用环境变量中serverAddr
中配置的地址作为Nacos服务端地址列表;
以上配置中的配置优先级顺序为默认情况下的优先级顺序, 不同的编程语言客户端的优先级可能存在差异,请根据实际情况修改;另外,如果设置了Java SDK 读取配置的优先级顺序,除了
ALIBABA_ALIWARE_ENDPOINT_URL
以外,其余的配置优先级顺序将会按照设置的优先级顺序进行读取。
2. 自定义的寻址方式
目前仅Java SDK支持自定义的寻址方式,其他语言的SDK暂不支持。
Nacos的Java SDK通过SPI,可以自定义ServerListProvider,实现自定义的寻址方式:
2.1. 引入依赖
2.2. 实现自定义ServerListProvider
实现接口com.alibaba.nacos.client.address.ServerListProvider
ServerListProvider的相应接口如果:
方法名 | 入参内容 | 返回内容 | 描述 |
---|---|---|---|
init | NacosClientProperties, NacosRestTemplate | void | 初始化时会调用此接口注入Nacos的配置,HTTP客户端等,以便于您读取初始化时传入的参数,以及通过HTTP接口访问获取其他信息等 |
getServerList | 无 | List<String> | ServerListManager 会调用此接口,获取服务端地址列表 |
getServerName | 无 | String | 获取ServerListProvider 所对应的服务端名称,用于标记地址列表所对应的服务端名称 |
getNamespace | 无 | String | 获取ServerListProvider 所归属的命名空间,也即此Nacos客户端所归属的命名空间 |
getContextPath | 无 | String | 获取ServerListProvider 所对应的服务端上下文路径,当Nacos服务端配置了上下文路径时,需要此上下文路径,以便于Nacos客户端访问服务端 |
getOrder | 无 | int | 获取ServerListProvider 的优先级,数字越大优先级越高,EndpointServerListProvider 的优先级为500 ,PropertiesServerListProvider 的优先级为499 |
match | NacosClientProperties | boolean | 判断当前ServerListProvider 是否匹配当前Nacos客户端的配置,如果匹配,则Nacos客户端会调用init 对此ServerListProvider 进行初始化 |
isFixed | 无 | boolean | 判断当前ServerListProvider 是否所提供的地址列表是否为固定的,比如EndpointServerListProvider 是可变的,PropertiesServerListProvider 是固定的 |
getAddressSource | 无 | String | 获取ServerListProvider 的地址列表来源地址,比如EndpointServerListProvider 返回是Endpoint 的地址,PropertiesServerListProvider 是“(空字符串) |
shutdown | 无 | void | 关闭ServerListProvider ,关闭时会调用此接口,以便于您关闭相关资源,比如关闭HTTP客户端等 |
2.3. 使用自定义ServerListProvider
添加对应的SPI配置文件META-INF/services/com.alibaba.nacos.client.address.ServerListProvider
到您的resources
目录中。
比如内容为:
随后在初始化时传入的Properties中配置能让自定义ServerListProvider匹配到的对应参数,比如代码为:
配置内容应该为: