# 服务接入 Nacos SDK 本文介绍不同框架的传统微服务如何接入 Nacos 的原生 SDK。 ## JAVA(无框架) 1. 在 `pom.xml` 文件中添加依赖项。目前的最新版本为 `2.2.2` ```xml com.alibaba.nacos nacos-client ${latest.version} ``` 2. 在服务中添加服务注册和服务发现的代码: ```java //添加配置变量 serverAddr: Nacos 的地址, e.g,: 192.168.0.0:8848. namespace: Nacos 中的命名空间 Properties properties = new Properties(); properties.setProperty("serverAddr", System.getProperty("serverAddr")); properties.setProperty("namespace", System.getProperty("namespace")); NamingService naming = NamingFactory.createNamingService(properties); //注册实例: 注册时带上服务的 IP 和端口 naming.registerInstance("sentinel-demo", "11.11.11.11", 8888, "DEFAULT"); System.out.println(naming.getAllInstances("sentinel-demo")); naming.deregisterInstance("sentinel-demo", "11.11.11.11", 8888, "DEFAULT"); System.out.println(naming.getAllInstances("sentinel-demo")); //添加对服务的订阅,在变更时获取事件通知 naming.subscribe("sentinel-demo", new EventListener() { @Override public void onEvent(Event event) { System.out.println(((NamingEvent)event).getServiceName()); System.out.println(((NamingEvent)event).getInstances()); } }); ``` 3. 如需添加 Nacos 的更多特性,可参考[更多使用方式](https://github.com/nacos-group/nacos-examples/tree/master/nacos-client-example) ## JAVA (SpringBoot) 框架 1. 在 `pom.xml` 文件中添加依赖项 ```xml com.alibaba.boot nacos-config-spring-boot-starter ${latest.version} ``` !!! note - 版本 [0.2.x.RELEASE](https://mvnrepository.com/artifact/com.alibaba.boot/nacos-config-spring-boot-starter) 对应的是 Spring Boot 2.x 版本。 - 版本 [0.1.x.RELEASE](https://mvnrepository.com/artifact/com.alibaba.boot/nacos-config-spring-boot-starter) 对应的是 Spring Boot 1.x 版本。 2. 在项目中添加 `bootstrap.yaml` 配置文件 ```yaml spring: application: name: demo nacos: config: data-id: test # Nacos 配置的 data-id server-addr: 127.0.0.1:8848 # Nacos 服务器地址 group: DEFAULT_GROUP # 配置文件 Group namespace: public # 命名空间 ID type: yaml # Nacos 配置文件类型 auto-refresh: true # 是否启用动态刷新配置 discovery: server-addr: 127.0.0.1:8848 # Nacos 服务器地址 group: DEFAULT_GROUP # 注册应用的 Group namespace: public # Nacos 的命名空间 ``` 3. 服务注册功能无需改动代码,直接启动项目就能在服务列表看到启动的服务。 4. 添加服务配置的代码 1. 登录 Nacos 控制台添加配置文件。 ![screenshot](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/skoala/images/standard01.png) 2. 然后在控制器代码中添加如下代码: ```java @RestController @RequestMapping("config") public class Controller { @NacosValue(value = "${a.test}", autoRefreshed = true) private String name; @GetMapping("get") public String get() { return this.name; } } ``` 5. 如需添加 Nacos 的更多特性,可参考[更多使用方式](https://github.com/nacos-group/nacos-examples/tree/master/nacos-spring-boot-example) ## JAVA (SpringCloud) 框架 1. 在 `pom.xml` 文件中添加依赖项。 版本对应关系参考:[版本说明](https://github.com/spring-cloud-incubator/spring-cloud-alibaba/wiki/版本说明) ```xml com.alibaba.cloud spring-cloud-starter-alibaba-nacos-config ${latest.version} com.alibaba.cloud spring-cloud-starter-alibaba-nacos-discovery ${latest.version} ``` 2. 在项目中添加 `bootstrap.yaml` 配置文件 ```java spring: application: name: demo --- spring: cloud: nacos: config: enabled: true server-addr: 127.0.0.1:8848 # nacos 服务器地址 name: test # nacos 配置的 data-id group: DEFAULT_GROUP # 配置文件 Group namespace: public # 命名空间ID file-extension: yaml # 配置文件后缀 discovery: enabled: true server-addr: 127.0.0.1:8848 # nacos 服务器地址 namespace: public # 命名空间ID group: DEFAULT_GROUP # 应用分组名 ``` 3. 在服务添加 Nacos 服务注册的代码 在启动类上添加 `@EnableDiscoveryClient` 注解开启服务注册 ```java @SpringBootApplication @EnableDiscoveryClient public class NacosProviderApplication { public static void main(String[] args) { SpringApplication.run(NacosProviderApplication.class, args); } } ``` 4. 添加动态配置的代码 1. 在 Nacos 控制台添加配置文件 ![screenshot](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/skoala/images/standard01.png) 2. 在控制器中添加 `@RefreshScope` 和 `@Value` 注解 通过 springcloud 的 `@RefreshScope` 注解可以实现自动配置 ```java @RestController @RequestMapping("config") @RefreshScope public class Controller { @Value(value = "${a.test}") private String name; @GetMapping("get") public String get() { return this.name; } } ``` 5. 如需添加 Nacos 的更多特性,可参考[更多使用方式](https://github.com/nacos-group/nacos-examples/tree/master/nacos-spring-cloud-example) ## Go 框架 在 Go 框架微服务中添加 Nacos SDK 时,需要满足以下两个前提条件: - Go 版本 1.15 以上 - Nacos 版本 2.x 以上 具体操作步骤如下: 1. 获取依赖 ```go go get -u github.com/nacos-group/nacos-sdk-go/v2 ``` 2. 在服务中添加服务注册的代码 ```go //create ServerConfig,配置 Nacos 服务器的地址 sc := []constant.ServerConfig{ *constant.NewServerConfig("127.0.0.1", 8848, constant.WithContextPath("/nacos")), } //create ClientConfig,配置客户端的链接配置 cc := *constant.NewClientConfig( constant.WithNamespaceId("public"), //命名空间 ID constant.WithTimeoutMs(5000), // 超时时间 constant.WithLogDir("/tmp/nacos/log"), //日志地址 constant.WithCacheDir("/tmp/nacos/cache"), // Nacos 服务缓存的地址 constant.WithLogLevel("debug"), // 日志级别 ) // 通过 ServerConfig 和 ClientConfig 创建 nacosclient 链接 client, err := clients.NewNamingClient( vo.NacosClientParam{ ClientConfig: &cc, ServerConfigs: sc, }, ) //Register 注册服务 registerServiceInstance(client, vo.RegisterInstanceParam{ Ip: "10.0.0.10", Port: 8848, ServiceName: "demo.go", GroupName: "group-a", ClusterName: "cluster-a", Weight: 10, Enable: true, Healthy: true, Ephemeral: true, Metadata: map[string]string{"idc": "shanghai"}, }) //DeRegister 注销服务 deRegisterServiceInstance(client, vo.DeregisterInstanceParam{ Ip: "10.0.0.10", Port: 8848, ServiceName: "demo.go", GroupName: "group-a", Cluster: "cluster-a", Ephemeral: true, //must be true }) ``` 3. 配置加载 ```go //create ServerConfig,配置 Nacos 服务器的地址 sc := []constant.ServerConfig{ *constant.NewServerConfig("127.0.0.1", 8848, constant.WithContextPath("/nacos")), } //create ClientConfig,配置客户端的链接配置 cc := *constant.NewClientConfig( constant.WithNamespaceId("public"), //命名空间 ID constant.WithTimeoutMs(5000), // 超时时间 constant.WithLogDir("/tmp/nacos/log"), //日志地址 constant.WithCacheDir("/tmp/nacos/cache"), // Nacos 服务缓存的地址 constant.WithLogLevel("debug"), // 日志级别 ) // 通过 ServerConfig 和 ClientConfig 创建 nacosclient 链接 client, err := clients.NewNamingClient( vo.NacosClientParam{ ClientConfig: &cc, ServerConfigs: sc, }, ) //get config 获取配置 content, err := client.GetConfig(vo.ConfigParam{ DataId: "test-data", Group: "test-group", }) fmt.Println("GetConfig,config :" + content) //Listen config change,key=dataId+group+namespaceId. 监听配置改变 err = client.ListenConfig(vo.ConfigParam{ DataId: "test-data", Group: "test-group", OnChange: func(namespace, group, dataId, data string) { fmt.Println("config changed group:" + group + ", dataId:" + dataId + ", content:" + data) }, }) ``` 4. 如需添加 Nacos 的更多特性,可参考[更多使用方式](https://github.com/nacos-group/nacos-sdk-go) ## Python 框架 1. 获取依赖 ```sh pip install nacos-sdk-python ``` 2. 代码接入 ```python import nacos # Nacos server地址 SERVER_ADDRESSES = "127.0.0.1:8848" # 命名空间 ID NAMESPACE = "public" client = nacos.NacosClient(SERVER_ADDRESSES, namespace=NAMESPACE) # 注册服务 client.add_naming_instance("test.service1", "1.0.0.7", 8080, "testCluster2", 0.2, "{}", False, True) # 发送心跳 client.send_heartbeat("test.service", "1.0.0.7", 8080, "testCluster2", 0.1, "{}") # get config data_id = "dev-config" group = "DEFAULT_GROUP" # 全局服务配置 server_config = json.loads(client.get_config(data_id, group)) # 当服务配置发生变化 def config_update(data): global server_config server_config = json.loads(data['content']) print('new data->', server_config) # 监听服务配置变化 client.add_config_watcher(data_id, group, config_update) ``` 3. 如需添加 Nacos 的更多特性,可参考[更多使用方式](https://github.com/nacos-group/nacos-sdk-python) ## Node.js 框架 1. 添加依赖 需要使用 `2.x` 以上的版本 ```shell npm install nacos --save ``` 2. 添加服务发现的代码逻辑 ```js 'use strict'; const NacosNamingClient = require('nacos').NacosNamingClient; const logger = console; const client = new NacosNamingClient({ logger, serverList: '127.0.0.1:8848', // Nacos 服务地址 namespace: 'public', //命名空间ID }); await client.ready(); const serviceName = 'nodejs.test.domain'; // 注册服务 await client.registerInstance(serviceName, { ip: '1.1.1.1', port: 8080, }); await client.registerInstance(serviceName, { ip: '2.2.2.2', port: 8080, }); // 订阅服务 client.subscribe(serviceName, hosts => { console.log(hosts); }); // 注销服务 await client.deregisterInstance(serviceName, { ip: '1.1.1.1', port: 8080, }); ``` 3. 添加动态配置的代码逻辑 ```js import {NacosConfigClient} from 'nacos'; // ts const NacosConfigClient = require('nacos').NacosConfigClient; // js const configClient = new NacosConfigClient({ serverAddr: '127.0.0.1:8848', namespace: 'public', //命名空间 ID }); // 获取配置文件 const content= await configClient.getConfig('test', 'DEFAULT_GROUP'); //dataID: test,group: DEFAULT_GROUP console.log('getConfig = ',content); // 监听配置变化 configClient.subscribe({ dataId: 'test', group: 'DEFAULT_GROUP', }, content => { console.log(content); }); ``` 4. 如需添加 Nacos 的更多特性,可参考[更多使用方式](https://github.com/nacos-group/nacos-sdk-nodejs) ## C++ 框架 1. 下载依赖 下载工程[源代码](https://github.com/nacos-group/nacos-sdk-cpp)并执行下述命令: ```sh cd nacos-sdk-cpp cmake . make ``` 执行命令后会产生一个 l`ibnacos-cli.so` 和一个 `nacos-cli.out` 文件 2. 运行 `make install` 将 `libnacos-cli` 安装到 `lib` 目录 3. 在服务代码中添加服务注册的代码逻辑 ```c++ #include #include #include "Nacos.h" using namespace std; using namespace nacos; int main() { Properties configProps; configProps[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1"; // nacos 服务地址 configProps[PropertyKeyConst::NAMESPACE] = "public"; // 命名空间ID NacosServiceFactory *factory = new NacosServiceFactory(configProps); ResourceGuard _guardFactory(factory); NamingService *namingSvc = factory->CreateNamingService(); ResourceGuard _serviceFactory(namingSvc); Instance instance; instance.clusterName = "DEFAULT"; instance.ip = "127.0.0.1"; instance.port = 2333; instance.instanceId = "1"; instance.ephemeral = true; //模拟注册5个服务 try { for (int i = 0; i < 5; i++) { NacosString serviceName = "TestNamingService" + NacosStringOps::valueOf(i); instance.port = 2000 + i; namingSvc->registerInstance(serviceName, instance); } } catch (NacosException &e) { cout << "encounter exception while registering service instance, raison:" << e.what() << endl; return -1; } sleep(30); //注销服务 try { for (int i = 0; i < 5; i++) { NacosString serviceName = "TestNamingService" + NacosStringOps::valueOf(i); namingSvc->deregisterInstance(serviceName, "127.0.0.1", 2000 + i); sleep(1); } } catch (NacosException &e) { cout << "encounter exception while registering service instance, raison:" << e.what() << endl; return -1; } sleep(30); return 0; } ``` 4. 添加动态配置的代码逻辑 ```c++ #include #include "Nacos.h" using namespace std; using namespace nacos; class MyListener : public Listener { private: int num; public: MyListener(int num) { this->num = num; } void receiveConfigInfo(const NacosString &configInfo) { cout << "===================================" << endl; cout << "Watcher" << num << endl; cout << "Watched Key UPDATED:" << configInfo << endl; cout << "===================================" << endl; } }; int main() { Properties props; props[PropertyKeyConst::SERVER_ADDR] = "127.0.0.1:8848"; //nacos地址 props[PropertyKeyConst::NAMESPACE] = "public"; // 命名空间ID NacosServiceFactory *factory = new NacosServiceFactory(props); ResourceGuard _guardFactory(factory); ConfigService *n = factory->CreateConfigService(); ResourceGuard _serviceFactory(n); MyListener *theListener = new MyListener(1);//You don't need to free it, since it will be deleted by the function removeListener n->addListener("dqid", "DEFAULT_GROUP", theListener);//dataID为"dqid"并且group为"DEFAULT_GROUP"的配置改变都将监听到 cout << "Input a character to continue" << endl; getchar(); cout << "remove listener" << endl; n->removeListener("dqid", NULLSTR, theListener);//取消监听 getchar(); return 0; } ``` 5. 如需添加 Nacos 的更多特性,可参考[更多使用方式](https://github.com/nacos-group/nacos-sdk-cpp/blob/master/README_zh_CN.md)