为什么叫Nacos?
Nacos 名字的由来(取红色的英文字符): Dynamic
Na
ming andCo
nfigurationS
ervice 动态命名和配置服务
Nacos 是什么?
Nacos 是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
Nacos 既可以作为注册中心也可以作为配置中心,相当于SpringCloud中 Eureka + Config 的组合,并且Eureka 注册中心已经宣布停止更新了,Nacos提供了比它们更强大的功能,并将其合二为一帮助开发者更容易构建分布式系统。
Nacos 作为注册中心在不同场景下可以切换成 CAP理论
中的 CP
或 AP
模式
Nacos 的主要功能有哪些?
-
服务发现与服务健康检测
-
动态配置服务
-
动态DNS服务
-
服务机器元数据管理
Nacos 资料地址
安装并运行 Nacos
下载安装包
预备环境准备
Nacos 依赖 Java 环境来运行。如果您是从代码开始构建并运行Nacos,还需要为此配置 Maven环境,请确保是在以下版本环境中安装使用:
启动服务器
Linux/Unix/Mac
启动命令(standalone代表着单机模式运行,非集群模式):
sh startup.sh -m standalone
如果您使用的是ubuntu系统,或者运行脚本报错提示[[符号找不到,可尝试如下运行:
bash startup.sh -m standalone
Windows
启动命令:
cmd startup.cmd
或者双击startup.cmd运行文件。
启动后打开Nacos服务地址 http://192.168.10.1:8848/nacos/index.html ,初始用户名和密码均是nacos。
服务注册&发现和配置管理
服务注册
curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=nacos.naming.serviceName&ip=20.18.7.10&port=8080'
服务发现
curl -X GET 'http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=nacos.naming.serviceName'
发布配置
curl -X POST "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test&content=HelloWorld"
获取配置
curl -X GET "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test"
关闭服务器
Linux/Unix/Mac
sh shutdown.sh
Windows
cmd shutdown.cmd
或者双击shutdown.cmd运行文件。
Nacos 管理界面介绍
下面是我们常见的nacos 界面,给大家介绍一个左侧的菜单功能
- 配置管理:指的是配置中心的管理
- 配置列表:展示所有的配置列表
- 历史版本:每次修改后的例时记录
- 监听查询
- 服务管理
- 服务列表
- 订阅者列表
- 权限控制
- 用户列表:登录nacos界面的用户管理
- 角色管理:用户所拥有的角色,需要绑定用户
- 权限管理:角色拥有的权限管理,需要绑定角色,对不同命名空间中的数据拥有的权限
- 命名空间:nacos 中根据不同命名空间区分不同服务,下面 dev 和 test 都是我自己配置的,可以编辑删除,public 是 nacos 默认保留的,不允许编辑和删除
- 集群管理
- 节点列表:Nacos 集群节点列表
Nacos 作为注册中心
本示例说明了如何使用 Nacos Discovery Starter 实现 SpringCloud 应用服务发现。
Nacos 是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
第一步: 创建一个普通的 SpringCloud 项目
第二步:在项目中添加 spring-cloud-starter-alibaba-nacos-discovery
完整 pom 文件如下所示:
<dependencies>
<!-- nacos discovery -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<!--spring cloud alibaba 2.2.0.RELEASE-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
第三步:/src/main/resources/application.properties 文件中添加Nacos服务地址相关配置
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 # nacos地址
application:
name: nacos-provider-server # 服务名
server:
port: 7001 # 端口号
第四步:主启动类中加入注解 @EnableDiscoveryClient 开启服务注册与发现
@SpringBootApplication
@EnableDiscoveryClient
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@RestController
class EchoController {
@GetMapping(value = "/echo/{string}")
public String echo(@PathVariable String string) {
return "Nacos server: " + string;
}
}
}
第五步:启动Nacos服务器
第六步:启动应用
浏览器访问 http://localhost:7001/echo/HelloWorld
查看Nacos服务器管理台界面,可以看到在服务列表中多了刚才启动的服务
Nacos 服务发现
为了便于使用,NacosServerList 实现了 com.netflix.loadbalancer.ServerList 接口,并在 @ConditionOnMissingBean 的条件下进行自动注入。如果您有定制化的需求,可以自己实现自己的 ServerList。
Nacos Discovery Starter 默认集成了 Ribbon ,所以对于使用了 Ribbon 做负载均衡的组件,可以直接使用 Nacos 的服务发现。
下面按照步骤创建项目 cloud-nacos-consumer-8001 服务,验证如何使用 RestTemplate 与 FeignClient
(1)添加 @LoadBlanced 注解,使得 RestTemplate 接入 Ribbon
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
(2)配置 FeignClient
@FeignClient(name = "nacos-provider-server")
public interface EchoService {
@GetMapping(value = "/echo/{str}")
String echo(@PathVariable("str") String str);
}
使用 @FeignClient 注解将 EchoService 这个接口包装成一个 FeignClient,属性 name 对应服务名 service-provider。
echo 方法上的 @RequestMapping 注解将 echo 方法与 URL "/echo/{str}" 相对应,@PathVariable 注解将 URL 路径中的 {str}
对应成 echo 方法的参数 str。
(3)完成以上配置后,将两者自动注入到 TestController 中。
@RestController
public class TestController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private EchoService echoService;
@GetMapping(value = "/echo-rest/{str}")
public String rest(@PathVariable String str) {
return restTemplate.getForObject("http://nacos-provider-server/echo/" + str, String.class);
}
@GetMapping(value = "/echo-feign/{str}")
public String feign(@PathVariable String str) {
return echoService.echo(str);
}
}
(4)启动项目
(5)在浏览器输入 http://localhost:8001/echo-rest/helloWorld, http://localhost:8001/echo-feign/helloWorld 访问成功
Nacos 服务注册与发现原理
服务注册
Spring Cloud Nacos Discovery 遵循了 spring cloud common 标准,实现了 AutoServiceRegistration、ServiceRegistry、Registration 这三个接口。
在 spring cloud 应用的启动阶段,监听了 WebServerInitializedEvent 事件,当Web容器初始化完成后,即收到 WebServerInitializedEvent 事件后,会触发注册的动作,调用 ServiceRegistry 的 register 方法,将服务注册到 Nacos Server。
服务发现
NacosServerList 实现了 com.netflix.loadbalancer.ServerList 接口,并在 @ConditionOnMissingBean 的条件下进行自动注入,默认集成了Ribbon。
如果需要有更加自定义的可以使用 @Autowired 注入一个 NacosRegistration 实例,通过其持有的 NamingService 字段内容直接调用 Nacos API。
Nacos 作为配置中心
Nacos 配置中心介绍
Nacos 配置中心支持 namespace(命名空间)、group(分组)、dataId(数据id) 三个属性确定一个配置
- namespace:即命名空间,可以配置成 dev、test、pro 用于切换不用环境的配置,
默认 public
- group:即分组,可以将同一个项目下的不用服务配置命名同一个分组统一管理,
默认 DEFAULT_GROUP
- dataId: 即数据id,通常
dataId = ${spring.application.name}.${file-extension:properties}
或者dataId =${spring.application.name}-${profile}.${file-extension:properties}
两种情况组成- 三者都可以在配置文件中自定义配置
namespace、group、dataId 三者之间的关系如下图所示

如何在SpringCloud项目中使用Nacos Config
- 添加依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
- 新建 bootstrap.yml 文件
spring:
application:
name: nacos-provider-server # 应用名
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848 # nacos 服务地址
server:
port: 7001 #端口号
- 如果需要使用域名配置nacos服务地址,格式必须按照
domain name:port
,例如 nacos.abc.com:80- file-extension 默认值为 properties
注意:根据前面介绍的dataId生成规则,这里的 dataId = ${spring.application.name}.${file-extension:properties}
即:dataId = nacos-provider-server.properties
- 主启动类中添加读取配置代码s
@SpringBootApplication
@EnableDiscoveryClient
public class NacosProviderMain7001 {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(NacosProviderMain7001.class, args);
String userName = applicationContext.getEnvironment().getProperty("user.name");
String userAge = applicationContext.getEnvironment().getProperty("user.age");
System.err.println("user name :" +userName+"; age: "+userAge);
}
@RestController
class EchoController {
@GetMapping(value = "/echo/{string}")
public String echo(@PathVariable String string) {
return "Nacos server: " + string;
}
}
}
- Nacos 服务器上添加 dataId = nacos-provider-server.properties 的配置
- 测试,启动项目
Nacos 配置动态刷新
- nacos 支持配置动态刷新
- nacos 配置动态刷新是默认开启的
- 如果想要关闭动态刷新功能,修改配置为
spring.cloud.nacos.config.refresh.enabled=false
即可关闭动态刷新- 如果需要在SpringBoot 配置类中动态读取 Nacos 配置有两种方式
- 配置类上加注解 @RefreshScope(springcloud 提供) ,配置属性上依然使用 @Value 注解
- 或者直接将配置属性上的@Value注解替换为@NacosValue(nacos 提供)注解,并设置autoRefreshed=true
- 测试代码
@SpringBootApplication
@EnableDiscoveryClient
public class NacosProviderMain7001 {
public static void main(String[] args) throws InterruptedException {
ConfigurableApplicationContext applicationContext = SpringApplication.run(NacosProviderMain7001.class, args);
while (true){
String userName = applicationContext.getEnvironment().getProperty("user.name");
String userAge = applicationContext.getEnvironment().getProperty("user.age");
System.err.println("user name :" +userName+"; age: "+userAge);
TimeUnit.SECONDS.sleep(1);
}
}
@RestController
class EchoController {
@GetMapping(value = "/echo/{string}")
public String echo(@PathVariable String string) {
return "Nacos server: " + string;
}
}
}
如果在项目启动过程中修改 nacos中的配置,那么控制台打印的结果也会随之变化
Nacos 集群与持久化配置
Nacos支持三种部署模式
- 单机模式 - 用于测试和单机试用。
- 集群模式 - 用于生产环境,确保高可用。
- 多集群模式 - 用于多数据中心场景