【Nacos】 SDK

Metadata

title: 【Nacos】 SDK
date: 2023-01-03 21:57
tags:
  - 行动阶段/完成
  - 主题场景/组件
  - 笔记空间/KnowladgeSpace/ProgramSpace/ModuleSpace
  - 细化主题/Module/Nacos/用户指南
categories:
  - Nacos
keywords:
  - Nacos
description: 【Nacos】 SDK

概述部分

Maven 坐标

<dependency>
    <groupId>com.alibaba.nacos</groupId>
    <artifactId>nacos-client</artifactId>
    <version>${version}</version>
</dependency>

注意:由于 Nacos Java SDK 在 2.0 版本后引入了 gRPC,为了避免用户业务引入的 gRPC 版本不同导致冲突,使用了 shaded 技术将部分依赖直接封装进 nacos-client 中,导致 nacos-client 较大。 如果用户未自行引入 gRPC 或确认版本无冲突,希望使用纯净版的 nacos-client 以减小依赖,可以使用 classifier 来指定使用纯净版。

<properties>
        <!-- 2.1.2版本以上支持纯净版客户端 -->
        <nacos.version>2.1.2</nacos.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
            <version>${nacos.version}</version>
            <!-- 指定纯净版SDK -->
            <classifier>pure</classifier>
        </dependency>
        <!-- 使用纯净版时必须要引入同版本nacos-api和nacos-common,否则可能出现运行时找不到类的问题 -->
        <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>nacos-common</artifactId>
            <version>${nacos.version}</version>
        </dependency>
        <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>nacos-api</artifactId>
            <version>${nacos.version}</version>
        </dependency>
    </dependencies>

配置管理

获取配置

描述

用于服务启动的时候从 Nacos 获取配置。

public String getConfig(String dataId, String group, long timeoutMs) throws NacosException

请求参数

参数名 参数类型 描述
dataId string 配置 ID,采用类似 package.class(如 com.taobao.tc.refund.log.level)的命名规则保证全局唯一性,class 部分建议是配置的业务含义。全部字符小写。只允许英文字符和 4 种特殊字符(”.“、”:“、”-“、”_“),不超过 256 字节。
group string 配置分组,建议填写产品名: 模块名(Nacos:Test)保证唯一性,只允许英文字符和 4 种特殊字符(”.“、”:“、”-“、”_“),不超过 128 字节。
timeout long 读取配置超时时间,单位 ms,推荐值 3000。

返回值

参数类型 描述
string 配置值

请求示例

try {
    String serverAddr = "{serverAddr}";
    String dataId = "{dataId}";
    String group = "{group}";
    Properties properties = new Properties();
    properties.put("serverAddr", serverAddr);
    ConfigService configService = NacosFactory.createConfigService(properties);
    String content = configService.getConfig(dataId, group, 5000);
    System.out.println(content);
} catch (NacosException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

异常说明

读取配置超时或网络异常,抛出 NacosException 异常。

监听配置

描述

如果希望 Nacos 推送配置变更,可以使用 Nacos 动态监听配置接口来实现。

public void addListener(String dataId, String group, Listener listener)

请求参数

参数名 参数类型 描述
dataId string 配置 ID,采用类似 package.class(如 com.taobao.tc.refund.log.level)的命名规则保证全局唯一性,class 部分建议是配置的业务含义。 全部字符小写。只允许英文字符和 4 种特殊字符(”.“、”:“、”-“、”_“)。不超过 256 字节。
group string 配置分组,建议填写产品名:模块名(如 Nacos:Test)保证唯一性。 只允许英文字符和 4 种特殊字符(”.“、”:“、”-“、”_“),不超过 128 字节。
listener Listener 监听器,配置变更进入监听器的回调函数。

返回值

参数类型 描述
string 配置值,初始化或者配置变更的时候通过回调函数返回该值。

请求示例

String serverAddr = "{serverAddr}";
String dataId = "{dataId}";
String group = "{group}";
Properties properties = new Properties();
properties.put("serverAddr", serverAddr);
ConfigService configService = NacosFactory.createConfigService(properties);
String content = configService.getConfig(dataId, group, 5000);
System.out.println(content);
configService.addListener(dataId, group, new Listener() {
    @Override
    public void receiveConfigInfo(String configInfo) {
        System.out.println("recieve1:" + configInfo);
    }
    @Override
    public Executor getExecutor() {
        return null;
    }
});

// 测试让主线程不退出,因为订阅配置是守护线程,主线程退出守护线程就会退出。 正式代码中无需下面代码
while (true) {
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

删除监听

描述

取消监听配置,取消监听后配置不会再推送。

public void removeListener(String dataId, String group, Listener listener)

请求参数

参数名 参数类型 描述
dataId string 配置 ID,采用类似 package.class(如 com.taobao.tc.refund.log.level)的命名规则保证全局唯一性,class 部分建议是配置的业务含义。全部字符小写。只允许英文字符和 4 种特殊字符(”.“、”:“、”-“、”_“),不超过 256 字节。
group string 配置分组
listener ConfigChangeListenerAdapter 监听器,配置变更进入监听器的回调函数。

使用示例

String serverAddr = "{serverAddr}";
String dataId = "{dataId}";
String group = "{group}";
Properties properties = new Properties();
properties.put("serverAddr", serverAddr);
ConfigService configService = NacosFactory.createConfigService(properties);
configService.removeListener(dataId, group, yourListener);

发布配置

描述

用于通过程序自动发布 Nacos 配置,以便通过自动化手段降低运维成本。

注意:创建和修改配置时使用的同一个发布接口,当配置不存在时会创建配置,当配置已存在时会更新配置。

public boolean publishConfig(String dataId, String group, String content) throws NacosException;

@Since 1.4.1
public boolean publishConfig(String dataId, String group, String content, String type) throws NacosException;

请求参数

参数名 参数类型 描述
dataId string 配置 ID,采用类似 package.class(如 com.taobao.tc.refund.log.level)的命名规则保证全局唯一性。建议根据配置的业务含义来定义 class 部分。全部字符均为小写。只允许英文字符和 4 种特殊字符(“.”、“:”、“-”、“_”),不超过 256 字节。
group string 配置分组,建议填写产品名:模块名(如 Nacos:Test)来保证唯一性。只允许英文字符和 4 种特殊字符(“.”、“:”、“-”、“_”),不超过 128 字节。
content string 配置内容,不超过 100K 字节。
type string @Since 1.4.1. 配置类型,见 com.alibaba.nacos.api.config.ConfigType,默认为 TEXT

返回参数

参数类型 描述
boolean 是否发布成功

请求示例

try {
    // 初始化配置服务,控制台通过示例代码自动获取下面参数
    String serverAddr = "{serverAddr}";
    String dataId = "{dataId}";
    String group = "{group}";
    Properties properties = new Properties();
    properties.put("serverAddr", serverAddr);
    ConfigService configService = NacosFactory.createConfigService(properties);
    boolean isPublishOk = configService.publishConfig(dataId, group, "content");
    System.out.println(isPublishOk);
} catch (NacosException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

异常说明

读取配置超时或网络异常,抛出 NacosException 异常。

删除配置

描述

用于通过程序自动删除 Nacos 配置,以便通过自动化手段降低运维成本。

注意: 当配置已存在时会删除该配置,当配置不存在时会直接返回成功消息。

public boolean removeConfig(String dataId, String group) throws NacosException

请求参数

参数名 参数类型 描述
dataId string 配置 ID
group string 配置分组

返回参数

参数类型 描述
boolean 是否删除成功

请求示例

try {
    // 初始化配置服务,控制台通过示例代码自动获取下面参数
    String serverAddr = "{serverAddr}";
    String dataId = "{dataId}";
    String group = "{group}";
    Properties properties = new Properties();
    properties.put("serverAddr", serverAddr);

    ConfigService configService = NacosFactory.createConfigService(properties);
    boolean isRemoveOk = configService.removeConfig(dataId, group);
    System.out.println(isRemoveOk);
} catch (NacosException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

异常说明

读取配置超时或网络异常,抛出 NacosException 异常。

服务发现 SDK

注册实例

描述注册一个实例到服务。

void registerInstance(String serviceName, String ip, int port) throws NacosException;

void registerInstance(String serviceName, String ip, int port, String clusterName) throws NacosException;

void registerInstance(String serviceName, Instance instance) throws NacosException;

请求参数

名称 类型 描述
serviceName 字符串 服务名
ip 字符串 服务实例 IP
port int 服务实例 port
clusterName 字符串 集群名
instance 参见代码注释 实例属性

返回参数

请求示例

NamingService naming = NamingFactory.createNamingService(System.getProperty("serveAddr"));
naming.registerInstance("nacos.test.3", "11.11.11.11", 8888, "TEST1");

Instance instance = new Instance();
instance.setIp("55.55.55.55");
instance.setPort(9999);
instance.setHealthy(false);
instance.setWeight(2.0);
Map<String, String> instanceMeta = new HashMap<>();
instanceMeta.put("site", "et2");
instance.setMetadata(instanceMeta);

Service service = new Service("nacos.test.4");
service.setApp("nacos-naming");
service.sethealthCheckMode("server");
service.setEnableHealthCheck(true);
service.setProtectThreshold(0.8F);
service.setGroup("CNCF");
Map<String, String> serviceMeta = new HashMap<>();
serviceMeta.put("symmetricCall", "true");
service.setMetadata(serviceMeta);
instance.setService(service);

Cluster cluster = new Cluster();
cluster.setName("TEST5");
AbstractHealthChecker.Http healthChecker = new AbstractHealthChecker.Http();
healthChecker.setExpectedResponseCode(400);
healthChecker.setCurlHost("USer-Agent|Nacos");
healthChecker.setCurlPath("/xxx.html");
cluster.setHealthChecker(healthChecker);
Map<String, String> clusterMeta = new HashMap<>();
clusterMeta.put("xxx", "yyyy");
cluster.setMetadata(clusterMeta);

instance.setCluster(cluster);

naming.registerInstance("nacos.test.4", instance);

注销实例

描述

删除服务下的一个实例。

void deregisterInstance(String serviceName, String ip, int port) throws NacosException;

void deregisterInstance(String serviceName, String ip, int port, String clusterName) throws NacosException;

请求参数

名称 类型 描述
serviceName 字符串 服务名
ip 字符串 服务实例 IP
port int 服务实例 port
clusterName 字符串 集群名

返回参数

请求示例

NamingService naming = NamingFactory.createNamingService(System.getProperty("serveAddr"));
naming.deregisterInstance("nacos.test.3", "11.11.11.11", 8888, "DEFAULT");

获取全部实例

描述

获取服务下的所有实例。

List<Instance> getAllInstances(String serviceName) throws NacosException;

List<Instance> getAllInstances(String serviceName, List<String> clusters) throws NacosException;

请求参数

名称 类型 描述
serviceName 字符串 服务名
clusters List 集群列表

返回参数

List 实例列表。

请求示例

NamingService naming = NamingFactory.createNamingService(System.getProperty("serveAddr"));
System.out.println(naming.getAllInstances("nacos.test.3"));

获取健康或不健康实例列表

描述

根据条件获取过滤后的实例列表。

List<Instance> selectInstances(String serviceName, boolean healthy) throws NacosException;

List<Instance> selectInstances(String serviceName, List<String> clusters, boolean healthy) throws NacosException;

请求参数

名称 类型 描述
serviceName 字符串 服务名
clusters List 集群列表
healthy boolean 是否健康

返回参数

List 实例列表。

请求示例

NamingService naming = NamingFactory.createNamingService(System.getProperty("serveAddr"));
System.out.println(naming.selectInstances("nacos.test.3", true));

获取一个健康实例

描述

根据负载均衡算法随机获取一个健康实例。

Instance selectOneHealthyInstance(String serviceName) throws NacosException;

Instance selectOneHealthyInstance(String serviceName, List<String> clusters) throws NacosException;

请求参数

名称 类型 描述
serviceName 字符串 服务名
clusters List 集群列表

返回参数

Instance 实例。

请求示例

NamingService naming = NamingFactory.createNamingService(System.getProperty("serveAddr"));
System.out.println(naming.selectOneHealthyInstance("nacos.test.3"));

监听服务

描述

监听服务下的实例列表变化。

void subscribe(String serviceName, EventListener listener) throws NacosException;

void subscribe(String serviceName, List<String> clusters, EventListener listener) throws NacosException;

请求参数

名称 类型 描述
serviceName 字符串 服务名
clusters List 集群列表
listener EventListener 回调 listener

返回参数

请求示例

NamingService naming = NamingFactory.createNamingService(System.getProperty("serveAddr"));
naming.subscribe("nacos.test.3", event -> {
    if (event instanceof NamingEvent) {
        System.out.println(((NamingEvent) event).getServceName());
        System.out.println(((NamingEvent) event).getInstances());
    }
});

取消监听服务

描述

取消监听服务下的实例列表变化。

void unsubscribe(String serviceName, EventListener listener) throws NacosException;

void unsubscribe(String serviceName, List<String> clusters, EventListener listener) throws NacosException;

请求参数

名称 类型 描述
serviceName 字符串 服务名
clusters List 集群列表
listener EventListener 回调 listener

返回参数

请求示例

NamingService naming = NamingFactory.createNamingService(System.getProperty("serveAddr"));
naming.unsubscribe("nacos.test.3", event -> {});

NacosClientProperties (Beta)

介绍

该类作为 client-sdk 参数配置总入口, 用于替代以前 properties 的方式. 该类共有 4 个取值范围, 分别是: 用户自定义、jvm 命令行参数、系统环境变量和默认配置.

该类可以指定取值范围优先级以改变查找顺序, 默认查找顺序: 用户自定义 ->jvm 命令行参数 -> 系统环境变量 -> 默认配置, 该类取值时会依次查找, 直到获取值为止.

目前还处于 beta 测试阶段, Naming 和 Config 入口处的 Properties 并未进行替换更改, 内部已经替换成 NacosClientProperties.

如何使用

// 设置一个全局共享的 key
NacosClientProperties.PROTOTYPE.setProperty("global-key1", "global-value1");

// 从全局共享配置中创建一个私有的配置
NacosClientProperties properties1 = NacosClientProperties.derive();
properties1.setProperty("private-key","value1");

String v1 = properties1.getProperty("private-key"); // v1 == value1
// 自身未能查找到 global-key1 向上查找
String v2 = properties1.getProperty("global-key1"); // v2 == global-value1

设计

NacosClientProperties 默认实现是 SearchableProperties, SearchableProperties 只能由 NacosClientProperties 接口中的 PROTOTYPE 进行派生. 派生可以理解为配置的一种继承.

配置继承

// 默认查找顺序: 用户自定义->jvm命令行参数->系统环境变量->默认配置

System.setProperty("jvm-key1", "jvm");

NacosClientProperties.PROTOTYPE.setProperty("global-key1", "value1");

// 派生出新配置
NacosClientProperties properties1 = NacosClientProperties.derive();
properties1.setProperty("properties1", "value2");

// 查找顺序为 自身 -> 父 properties -> jvm -> system env -> default-setting
String v1 = properties1.getProperty("global-key1"); //  v1 == value1 
String v2 = properties1.getProperty("jvm-key1"); // v2 == jvm

NacosClientProperties properties2 = properties1.derive();
properties2.getProperty("properties1");

// 查找顺序为 自身 -> 父 properties -> 父 properties -> jvm -> system env -> default-setting
String v3 = properties2.getProperty("properties1"); // v3 == value2

查找优先级

取值范围总共分为 4 个:

  • PROPERTIES (用户自定义)
  • JVM (jvm 命令行参数)
  • ENV (系统环境变量)
  • DEFAULT_SETTING (默认配置)

默认查找顺序为: PROPERTIES->JVM->ENV->DEFAULT_SETTING

修改取值范围优先级可通过java -Dnacos.env.first=PROPERTIES|JVM|ENV|DEFAULT_SETTING 或者设置环境变量 NACOS_ENV_FIRST=PROPERTIES|JVM|ENV|DEFAULT_SETTING的方式指定. 指定之后, 会优先查找指定的取值范围

对于 client 中的 logging 支持

目前 client 中的 log42 和 logback 均完成 NacosClientProperties 的适配, 可以通过以上 4 个取值范围来控制 log xml 配置文件中的参数值