Nacos初识学习入门:新手快速上手指南
Nacos是一款由阿里巴巴开源的服务发现、配置管理和服务管理平台,适用于微服务架构和云原生应用等场景。本文将详细介绍Nacos的主要功能和使用场景,并通过示例代码展示如何进行服务注册与发现和配置管理。本文还将指导你如何安装和配置Nacos环境,帮助你快速上手。
Nacos简介
Nacos 是阿里巴巴开源的一款动态服务发现、配置管理和服务管理平台。它可以帮助开发者在分布式系统中,动态管理服务、配置和服务的生命周期。Nacos 支持多个编程语言和异构环境,适用于微服务架构、云原生应用、容器编排等场景。
Nacos的主要功能
- 服务发现与服务健康监测:提供服务注册、发现和健康状态监测功能,支持多种服务发现策略。
- 动态配置服务:支持动态配置管理,可以动态更新配置并推送配置变更通知。
- 动态服务管理:提供服务管理功能,支持服务元数据管理和服务生命周期管理。
- 多环境支持:支持多环境部署,如开发、测试和生产环境,可以按环境管理配置和服务。
- 多租户支持:支持多租户模型,可以按租户隔离配置和服务。
- 全链路监控:提供服务监控功能,可以监控服务的调用链路和服务的性能指标。
- 可视化管理:提供可视化管理界面,方便管理员和开发人员进行服务管理和配置。
Nacos的使用场景
- 微服务架构:在微服务架构中,Nacos可以用于服务注册与发现,使服务之间能够动态发现并调用。
- 配置管理:在分布式系统中,Nacos可以用于统一管理和动态更新配置,使配置项更加灵活。
- 服务管理:在大型分布式系统中,Nacos可以用于管理服务元数据和服务生命周期,支持服务的全生命周期管理。
- 云原生应用:在云原生应用中,Nacos可以用于服务发现、配置管理和全链路监控,使应用更加灵活和可靠。
- 容器编排:在容器编排环境中,Nacos可以用于服务注册与发现,支持容器的动态调度和服务发现。
安装与配置Nacos
下载Nacos
首先,从 Nacos 的官方 GitHub 仓库下载 Nacos 的最新版本。可以访问 Nacos 的 GitHub 仓库下载页面,根据自己的操作系统选择相应的版本进行下载。
下载完成后,解压文件,进入 Nacos 的解压目录。
wget https://github.com/alibaba/Nacos/releases/download/2.0.4/nacos-server-2.0.4.tar.gz
tar -xvf nacos-server-2.0.4.tar.gz
cd nacos
安装与启动Nacos服务
Nacos 提供了三种启动模式:单机模式、集群模式和分组集群模式。这里我们以单机模式为例,介绍如何启动 Nacos 服务。
-
启动MySQL数据库(仅适用于单机模式)
如果使用单机模式部署,需要先启动 MySQL 数据库,并创建 Nacos 所需的数据库和表结构。可以使用以下 SQL 语句创建数据库和表结构:CREATE DATABASE nacos_config DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; CREATE DATABASE nacos_naming DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; CREATE DATABASE nacos_config_history DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; USE nacos_config; -- 创建 nacos_config 表 CREATE TABLE `config_info` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', `data_id` varchar(255) NOT NULL COMMENT 'dataId', `group_id` varchar(255) NOT NULL COMMENT 'group', `content` mediumtext NOT NULL COMMENT 'content', `md5` varchar(32) DEFAULT NULL, `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', `src_user` text COMMENT 'source user', `src_ip` varchar(20) COMMENT 'source ip', `app_name` varchar(128) DEFAULT NULL, `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段', `c_desc` varchar(256) DEFAULT NULL, `c_use` varchar(64) DEFAULT NULL, `effect` varchar(64) DEFAULT NULL, `type` varchar(64) DEFAULT NULL, `c_schema` text, PRIMARY KEY (`id`), UNIQUE KEY `key_configinfo_dataidgroupversioncst` (`data_id`,`group_id`,`tenant_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='config_info'; USE nacos_naming; -- 创建 nacos_naming 表 CREATE TABLE `tb_inst` ( `id` int(11) NOT NULL AUTO_INCREMENT, `app_name` varchar(255) NOT NULL, `ip` varchar(64) NOT NULL, `ctime` datetime NOT NULL, `mtime` datetime NOT NULL, `deleted` bit(1) NOT NULL, `port_count` int(11) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `UK_app_name_ip` (`app_name`,`ip`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Instance'; CREATE TABLE `tb_naming` ( `id` int(11) NOT NULL AUTO_INCREMENT, `app_name` varchar(255) NOT NULL, `ip` varchar(64) NOT NULL, `ctime` datetime NOT NULL, `mtime` datetime NOT NULL, `deleted` bit(1) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `UK_app_name_ip` (`app_name`,`ip`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Naming';
-
启动 Nacos 服务
进入bin
目录,运行启动脚本,启动 Nacos 服务。cd nacos/bin ./startup.sh -m standalone
配置Nacos环境变量
为了方便使用 Nacos,可以配置 Nacos 的环境变量。假设 Nacos 安装在 /opt/nacos
目录下,可以设置环境变量如下:
export NACOS_HOME=/opt/nacos/nacos
export PATH=$PATH:$NACOS_HOME/bin
启动后,可以访问 Nacos 的 Web 界面,地址为 http://localhost:8848/nacos
,默认用户名和密码均为 nacos
。
基本概念与术语
服务注册与发现
服务注册与发现是 Nacos 的核心功能之一。服务注册是指服务提供者将自身注册到 Nacos 中,服务发现是指服务消费者从 Nacos 中获取服务提供者的地址列表,并动态调用服务。
-
服务注册
服务注册是指将服务提供者的信息注册到 Nacos 中。服务提供者将服务名称、服务地址、端口等信息注册到 Nacos 中,Nacos 会将这些信息存储到数据库中,并维护服务的健康状态。示例代码如下:
// 服务注册示例代码 public class ServiceRegistrar { public void registerService(String serviceName, String serviceIP, int servicePort) { // 注册服务到Nacos NamingService namingService = NacosFactory.createNamingService("localhost:8848"); Instance instance = new Instance(); instance.setIp(serviceIP); instance.setPort(servicePort); instance.setServiceName(serviceName); instance.setHealthy(true); try { namingService.registerInstance(serviceName, instance); } catch (NacosException e) { e.printStackTrace(); } } }
-
服务发现
服务发现是指服务消费者从 Nacos 中获取服务提供者的地址列表,并动态调用服务。服务消费者向 Nacos 发起服务发现请求,Nacos 根据服务名称返回服务提供者的地址列表,服务消费者根据返回的地址列表进行服务调用。示例代码如下:
// 服务发现示例代码 public class ServiceDiscoverer { public List<String> discoverService(String serviceName) { List<String> serviceIPs = new ArrayList<>(); try { NamingService namingService = NacosFactory.createNamingService("localhost:8848"); List<Instance> instances = namingService.getAllInstances(serviceName); for (Instance instance : instances) { serviceIPs.add("http://" + instance.getIp() + ":" + instance.getPort()); } } catch (NacosException e) { e.printStackTrace(); } return serviceIPs; } }
配置管理
Nacos 的配置管理功能支持动态配置管理,可以动态更新配置并推送配置变更通知。配置管理包括创建配置项、获取配置、更新配置和删除配置等操作。
-
创建配置项
创建配置项是指在 Nacos 中创建一个新的配置项,并指定配置项的名称、配置内容和配置组等信息。配置项创建后,可以被服务提供者和服务消费者使用。示例代码如下:
// 创建配置项示例代码 public void createConfiguration(String dataId, String group, String content) { ConfigService configService = NacosFactory.createConfigService(dataId, group, "localhost:8848"); try { configService.publishConfig(dataId, group, content); } catch (NacosException e) { e.printStackTrace(); } }
-
获取配置
获取配置是指从 Nacos 中获取指定配置项的配置内容。配置项获取后,可以根据配置内容进行后续操作。示例代码如下:
// 获取配置示例代码 public String getConfig(String dataId, String group) { ConfigService configService = NacosFactory.createConfigService(dataId, group, "localhost:8848"); try { String configContent = configService.getConfig(dataId, group, 5000); return configContent; } catch (NacosException e) { e.printStackTrace(); return null; } }
-
更新配置
更新配置是指在 Nacos 中更新指定配置项的配置内容。更新配置项后,可以实时推送配置变更通知,使服务提供者和服务消费者能够及时获取最新的配置内容。示例代码如下:
// 更新配置示例代码 public void updateConfig(String dataId, String group, String content) { ConfigService configService = NacosFactory.createConfigService(dataId, group, "localhost:8848"); try { configService.updateConfig(dataId, group, content); } catch (NacosException e) { e.printStackTrace(); } }
-
删除配置
删除配置是指从 Nacos 中删除指定配置项。删除配置项后,配置项将不可用。示例代码如下:
// 删除配置示例代码 public void deleteConfig(String dataId, String group) { ConfigService configService = NacosFactory.createConfigService(dataId, group, "localhost:8848"); try { configService.removeConfig(dataId, group); } catch (NacosException e) { e.printStackTrace(); } }
服务管理
Nacos 的服务管理功能支持服务元数据管理和服务生命周期管理。服务管理包括服务注册、服务发现、服务监控和服务元数据管理等操作。
-
服务注册
服务注册是指将服务提供者的信息注册到 Nacos 中。服务提供者将服务名称、服务地址、端口等信息注册到 Nacos 中,Nacos 会将这些信息存储到数据库中,并维护服务的健康状态。示例代码如下:
// 服务注册示例代码 public class ServiceRegistrar { public void registerService(String serviceName, String serviceIP, int servicePort) { // 注册服务到Nacos NamingService namingService = NacosFactory.createNamingService("localhost:8848"); Instance instance = new Instance(); instance.setIp(serviceIP); instance.setPort(servicePort); instance.setServiceName(serviceName); instance.setHealthy(true); try { namingService.registerInstance(serviceName, instance); } catch (NacosException e) { e.printStackTrace(); } } }
-
服务发现
服务发现是指服务消费者从 Nacos 中获取服务提供者的地址列表,并动态调用服务。服务消费者向 Nacos 发起服务发现请求,Nacos 根据服务名称返回服务提供者的地址列表,服务消费者根据返回的地址列表进行服务调用。示例代码如下:
// 服务发现示例代码 public class ServiceDiscoverer { public List<String> discoverService(String serviceName) { List<String> serviceIPs = new ArrayList<>(); try { NamingService namingService = NacosFactory.createNamingService("localhost:8848"); List<Instance> instances = namingService.getAllInstances(serviceName); for (Instance instance : instances) { serviceIPs.add("http://" + instance.getIp() + ":" + instance.getPort()); } } catch (NacosException e) { e.printStackTrace(); } return serviceIPs; } }
-
服务监控
服务监控是指监控服务的调用链路和服务的性能指标。服务监控可以实时监控服务的调用情况,发现服务的性能瓶颈和异常情况。示例代码如下:
// 服务监控示例代码 public class ServiceMonitor { public void monitorService(String serviceName) { try { MonitorService monitorService = NacosFactory.createMonitorService("localhost:8848"); List<MonitorData> monitorDataList = monitorService.getMonitorData(serviceName); // 处理监控数据 } catch (NacosException e) { e.printStackTrace(); } } }
-
服务元数据管理
服务元数据管理是指管理服务的元数据信息,如服务名称、服务地址、服务端口等。服务元数据管理可以维护服务的元数据信息,方便服务管理和配置管理。示例代码如下:
// 服务元数据管理示例代码 public class ServiceMetadataManager { public void manageMetadata(String serviceName, String serviceIP, int servicePort) { try { NamingService namingService = NacosFactory.createNamingService("localhost:8848"); Instance instance = new Instance(); instance.setIp(serviceIP); instance.setPort(servicePort); instance.setServiceName(serviceName); instance.setHealthy(true); namingService.registerInstance(serviceName, instance); } catch (NacosException e) { e.printStackTrace(); } } }
动手实践:服务注册与发现
创建服务实例
服务注册是指将服务提供者的信息注册到 Nacos 中,服务提供者将服务名称、服务地址、端口等信息注册到 Nacos 中,Nacos 会将这些信息存储到数据库中,并维护服务的健康状态。
-
编写服务提供者代码
服务提供者需要将自身注册到 Nacos 中。下面是一个简单的 Java 服务提供者的示例代码,该代码将一个服务实例注册到 Nacos 中。// 服务提供者示例代码 public class ServiceProvider { public static void main(String[] args) { String serviceName = "userService"; String serviceIP = "127.0.0.1"; int servicePort = 8080; // 注册服务到Nacos NamingService namingService = NacosFactory.createNamingService("localhost:8848"); Instance instance = new Instance(); instance.setIp(serviceIP); instance.setPort(servicePort); instance.setServiceName(serviceName); instance.setHealthy(true); try { namingService.registerInstance(serviceName, instance); System.out.println("Service registered successfully."); } catch (NacosException e) { e.printStackTrace(); } } }
服务发现与调用
服务发现是指服务消费者从 Nacos 中获取服务提供者的地址列表,并动态调用服务。服务消费者向 Nacos 发起服务发现请求,Nacos 根据服务名称返回服务提供者的地址列表,服务消费者根据返回的地址列表进行服务调用。
-
编写服务消费者代码
服务消费者需要从 Nacos 中获取服务提供者的地址列表,并调用服务。下面是一个简单的 Java 服务消费者的示例代码,该代码从 Nacos 中获取服务提供者的地址列表,并调用服务。// 服务消费者示例代码 public class ServiceConsumer { public static void main(String[] args) { String serviceName = "userService"; try { NamingService namingService = NacosFactory.createNamingService("localhost:8848"); List<Instance> instances = namingService.getAllInstances(serviceName); for (Instance instance : instances) { String serviceAddress = "http://" + instance.getIp() + ":" + instance.getPort(); System.out.println("Calling service at address: " + serviceAddress); // 这里可以调用服务,例如使用HttpClient } } catch (NacosException e) { e.printStackTrace(); } } }
测试服务注册与发现
-
启动服务提供者
先启动服务提供者,将服务实例注册到 Nacos 中。java -jar service-provider.jar
-
启动服务消费者
然后启动服务消费者,从 Nacos 中获取服务提供者的地址列表,并调用服务。java -jar service-consumer.jar
- 验证服务注册与发现
在 Nacos 的 Web 界面中,可以查看服务实例的注册情况。服务提供者成功注册后,服务消费者可以从 Nacos 中获取服务提供者的地址列表,并调用服务。可以通过打印日志来验证服务调用是否成功。
动手实践:配置管理
创建配置项
配置管理是指在 Nacos 中创建一个新的配置项,并指定配置项的名称、配置内容和配置组等信息。配置项创建后,可以被服务提供者和服务消费者使用。
-
编写创建配置项的代码
下面是一个简单的 Java 代码示例,该代码在 Nacos 中创建一个新的配置项。// 创建配置项的示例代码 public class ConfigCreator { public static void main(String[] args) { String dataId = "user-config"; String group = "DEFAULT_GROUP"; String content = "username=admin,password=123456"; ConfigService configService = NacosFactory.createConfigService(dataId, group, "localhost:8848"); try { configService.publishConfig(dataId, group, content); System.out.println("Configuration created successfully."); } catch (NacosException e) { e.printStackTrace(); } } }
获取配置
获取配置是指从 Nacos 中获取指定配置项的配置内容。配置项获取后,可以根据配置内容进行后续操作。
-
编写获取配置的代码
下面是一个简单的 Java 代码示例,该代码从 Nacos 中获取指定配置项的配置内容。// 获取配置的示例代码 public class ConfigGetter { public static void main(String[] args) { String dataId = "user-config"; String group = "DEFAULT_GROUP"; ConfigService configService = NacosFactory.createConfigService(dataId, group, "localhost:8848"); try { String configContent = configService.getConfig(dataId, group, 5000); System.out.println("Configuration content: " + configContent); } catch (NacosException e) { e.printStackTrace(); } } }
更新配置
更新配置是指在 Nacos 中更新指定配置项的配置内容。更新配置项后,可以实时推送配置变更通知,使服务提供者和服务消费者能够及时获取最新的配置内容。
-
编写更新配置的代码
下面是一个简单的 Java 代码示例,该代码在 Nacos 中更新指定配置项的配置内容。// 更新配置的示例代码 public class ConfigUpdater { public static void main(String[] args) { String dataId = "user-config"; String group = "DEFAULT_GROUP"; String content = "username=admin,password=654321"; ConfigService configService = NacosFactory.createConfigService(dataId, group, "localhost:8848"); try { configService.updateConfig(dataId, group, content); System.out.println("Configuration updated successfully."); } catch (NacosException e) { e.printStackTrace(); } } }
删除配置
删除配置是指从 Nacos 中删除指定配置项。删除配置项后,配置项将不可用。
-
编写删除配置的代码
下面是一个简单的 Java 代码示例,该代码在 Nacos 中删除指定配置项。// 删除配置的示例代码 public class ConfigDeleter { public static void main(String[] args) { String dataId = "user-config"; String group = "DEFAULT_GROUP"; ConfigService configService = NacosFactory.createConfigService(dataId, group, "localhost:8848"); try { configService.removeConfig(dataId, group); System.out.println("Configuration deleted successfully."); } catch (NacosException e) { e.printStackTrace(); } } }
常见问题与解决方案
常见问题汇总
- Nacos 服务启动失败
- 无法注册服务
- 无法发现服务
- 配置项创建失败
- 配置项获取失败
- 配置项更新失败
- 配置项删除失败
- 服务监控信息获取失败
- 服务元数据管理失败
解决方案与建议
-
Nacos 服务启动失败
- 确保 MySQL 数据库已启动并正常运行。
- 检查 Nacos 的配置文件是否正确配置了数据库连接信息。
- 确保 Nacos 的启动脚本执行成功,查看日志文件获取更多信息。
示例代码如下:
# 检查 MySQL 是否启动 systemctl status mysql
-
无法注册服务
- 确保 Nacos 服务已启动并正常运行。
- 检查服务注册代码是否正确配置了服务名称、服务地址和端口。
- 确保服务注册的地址和端口是可用的。
- 查看 Nacos 的日志文件获取更多信息。
示例代码如下:
// 服务注册示例代码 public class ServiceRegistrar { // 检查服务注册代码是否正确配置了服务名称、服务地址和端口 public void registerService(String serviceName, String serviceIP, int servicePort) { NamingService namingService = NacosFactory.createNamingService("localhost:8848"); Instance instance = new Instance(); instance.setIp(serviceIP); instance.setPort(servicePort); instance.setServiceName(serviceName); instance.setHealthy(true); try { namingService.registerInstance(serviceName, instance); } catch (NacosException e) { e.printStackTrace(); } } }
-
无法发现服务
- 确保服务已成功注册到 Nacos 中。
- 检查服务发现代码是否正确配置了服务名称。
- 确保服务发现的地址和端口是可用的。
- 查看 Nacos 的日志文件获取更多信息。
示例代码如下:
// 服务发现示例代码 public class ServiceDiscoverer { public List<String> discoverService(String serviceName) { List<String> serviceIPs = new ArrayList<>(); try { NamingService namingService = NacosFactory.createNamingService("localhost:8848"); List<Instance> instances = namingService.getAllInstances(serviceName); for (Instance instance : instances) { serviceIPs.add("http://" + instance.getIp() + ":" + instance.getPort()); } } catch (NacosException e) { e.printStackTrace(); } return serviceIPs; } }
-
配置项创建失败
- 确保 Nacos 服务已启动并正常运行。
- 检查配置项创建代码是否正确配置了数据 ID、组名和配置内容。
- 确保配置项的名称和组名是唯一的。
- 查看 Nacos 的日志文件获取更多信息。
示例代码如下:
// 创建配置项示例代码 public class ConfigCreator { public void createConfiguration(String dataId, String group, String content) { ConfigService configService = NacosFactory.createConfigService(dataId, group, "localhost:8848"); try { configService.publishConfig(dataId, group, content); } catch (NacosException e) { e.printStackTrace(); } } }
-
配置项获取失败
- 确保配置项已成功创建。
- 检查配置项获取代码是否正确配置了数据 ID 和组名。
- 确保 Nacos 服务器地址和端口是正确的。
- 查看 Nacos 的日志文件获取更多信息。
示例代码如下:
// 获取配置示例代码 public class ConfigGetter { public String getConfig(String dataId, String group) { ConfigService configService = NacosFactory.createConfigService(dataId, group, "localhost:8848"); try { String configContent = configService.getConfig(dataId, group, 5000); return configContent; } catch (NacosException e) { e.printStackTrace(); return null; } } }
-
配置项更新失败
- 确保配置项已成功创建。
- 检查配置项更新代码是否正确配置了数据 ID、组名和配置内容。
- 确保 Nacos 服务器地址和端口是正确的。
- 查看 Nacos 的日志文件获取更多信息。
示例代码如下:
// 更新配置示例代码 public class ConfigUpdater { public void updateConfig(String dataId, String group, String content) { ConfigService configService = NacosFactory.createConfigService(dataId, group, "localhost:8848"); try { configService.updateConfig(dataId, group, content); } catch (NacosException e) { e.printStackTrace(); } } }
-
配置项删除失败
- 确保配置项已成功创建。
- 检查配置项删除代码是否正确配置了数据 ID 和组名。
- 确保 Nacos 服务器地址和端口是正确的。
- 查看 Nacos 的日志文件获取更多信息。
示例代码如下:
// 删除配置示例代码 public class ConfigDeleter { public void deleteConfig(String dataId, String group) { ConfigService configService = NacosFactory.createConfigService(dataId, group, "localhost:8848"); try { configService.removeConfig(dataId, group); } catch (NacosException e) { e.printStackTrace(); } } }
-
服务监控信息获取失败
- 确保 Nacos 服务已启动并正常运行。
- 检查监控代码是否正确配置了服务名称。
- 确保 Nacos 服务器地址和端口是正确的。
- 查看 Nacos 的日志文件获取更多信息。
示例代码如下:
// 服务监控示例代码 public class ServiceMonitor { public void monitorService(String serviceName) { try { MonitorService monitorService = NacosFactory.createMonitorService("localhost:8848"); List<MonitorData> monitorDataList = monitorService.getMonitorData(serviceName); // 处理监控数据 } catch (NacosException e) { e.printStackTrace(); } } }
-
服务元数据管理失败
- 确保 Nacos 服务已启动并正常运行。
- 检查元数据管理代码是否正确配置了服务名称、服务地址和端口。
- 确保 Nacos 服务器地址和端口是正确的。
- 查看 Nacos 的日志文件获取更多信息。
示例代码如下:
// 服务元数据管理示例代码 public class ServiceMetadataManager { public void manageMetadata(String serviceName, String serviceIP, int servicePort) { try { NamingService namingService = NacosFactory.createNamingService("localhost:8848"); Instance instance = new Instance(); instance.setIp(serviceIP); instance.setPort(servicePort); instance.setServiceName(serviceName); instance.setHealthy(true); namingService.registerInstance(serviceName, instance); } catch (NacosException e) { e.printStackTrace(); } } }
社区与文档资源
- 官方文档:Nacos 的官方文档提供了详细的安装、配置和使用说明,可以在 Nacos 的 GitHub 仓库中找到。
- GitHub 仓库:Nacos 的 GitHub 仓库包含了源代码和最新版本,也可以在这里找到开发指南和一些示例代码。
- 社区支持:Nacos 有一个活跃的社区,可以在 GitHub Issues 或邮件列表中寻求帮助和交流。
- 博客与教程:网络上有很多关于 Nacos 的博客和教程,可以在慕课网等编程学习网站上找到。
- 论坛与讨论组:可以在阿里云论坛或 Stack Overflow 上找到关于 Nacos 的讨论和问题解答。
- 视频教程:阿里云或慕课网等视频平台上有许多关于 Nacos 的视频教程,可以边看边学。
通过以上介绍和示例,希望能帮助你快速上手 Nacos,并在实际项目中充分利用它的功能。
共同学习,写下你的评论
评论加载中...
作者其他优质文章