Nacos 是阿里巴巴开源的一款功能强大的动态服务发现、配置管理和服务管理平台。在微服务架构中,它扮演着"注册中心"和"配置中心"的双重角色,完美替代了 Eureka 和 Spring Cloud Config。
本教程将基于 Spring Boot 3.x 和 Spring Cloud Alibaba 2022.x,手把手教你如何从零搭建 Nacos 环境,并实现服务的注册发现与配置的动态刷新。
环境准备与 Nacos 服务端启动
在开始编写代码之前,我们需要先拥有一个运行中的 Nacos 服务端。
- 下载 Nacos
访问 Nacos 官方 GitHub 发布页,下载最新稳定版(如 2.x 版本)的压缩包并解压。 - 单机模式启动
Nacos 默认是以集群模式启动的,如果是本地学习或开发测试,必须指定为单机模式,否则会因找不到集群配置而启动失败。
进入 Nacos 的 bin 目录,执行以下命令:
- Windows :
startup.cmd -m standalone - Linux/Mac :
sh startup.sh -m standalone
- 访问控制台
启动成功后,打开浏览器访问http://127.0.0.1:8848/nacos。
- 默认账号 :
nacos - 默认密码 :
nacos
核心依赖与基础配置
我们将创建一个标准的 Spring Boot 项目,并引入 Nacos 的相关依赖。
- Maven 依赖
确保你的pom.xml中包含以下核心依赖。注意版本管理,这里使用的是 Spring Cloud Alibaba 的 Starter。
xml
<dependencies>
<!-- Nacos 服务发现依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Nacos 配置中心依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- Web 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Actuator 用于刷新配置(可选,但推荐) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<!-- 引入 Spring Cloud Alibaba 的版本管理 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2022.0.0.0</version> <!-- 请根据 Spring Boot 版本选择对应版本 -->
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
- 配置 bootstrap.yml
这是最关键的一步。为了让 Nacos 配置中心在应用启动的早期阶段生效,必须将 Nacos 的连接配置写在bootstrap.yml(或bootstrap.properties)中,而不是application.yml中。因为bootstrap的加载优先级高于application。
yaml
spring:
application:
name: nacos-demo-service # 服务名,也是 Nacos 中 Data ID 的前缀
cloud:
nacos:
# 配置中心地址
config:
server-addr: 127.0.0.1:8848
file-extension: yaml # 配置文件格式
# namespace: public # 如果需要隔离环境,填写命名空间 ID
# group: DEFAULT_GROUP # 默认分组
# 服务注册中心地址
discovery:
server-addr: 127.0.0.1:8848
# 暴露刷新端点,用于手动触发配置刷新(如果不使用自动刷新)
management:
endpoints:
web:
exposure:
include: refresh
实战一:配置中心与动态刷新
我们将演示如何从 Nacos 获取配置,并在不重启服务的情况下动态修改配置。
- 在 Nacos 控制台发布配置
- 登录 Nacos 控制台,进入"配置管理" -> "配置列表"。
- 点击"+"号新建配置。
- Data ID :
nacos-demo-service.yaml(必须与spring.application.name+file-extension对应)。 - 配置内容:
yaml
message: "Hello from Nacos Config!"
feature-enabled: true
- 点击"发布"。
- 编写代码读取配置
使用@RefreshScope注解是实现配置热更新的关键。当 Nacos 中的配置发生变化时,Spring 容器会自动重新注入最新的值。
java
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RefreshScope // 开启配置动态刷新
public class ConfigController {
@Value("${message:Default Message}")
private String message;
@Value("${feature-enabled:false}")
private boolean featureEnabled;
@GetMapping("/config")
public String getConfig() {
return "当前配置: " + message + ", 功能开关: " + featureEnabled;
}
}
- 验证效果
- 启动应用,访问
http://localhost:8080/config,你会看到 Nacos 中的配置内容。 - 回到 Nacos 控制台,修改
message的值为 "Hello World Updated!" 并发布。 - 无需重启应用,再次刷新浏览器接口,你会发现配置已经实时生效。
实战二:服务注册与发现
接下来,我们将演示如何让服务注册到 Nacos,并让另一个服务发现它。
- 服务提供者
假设我们有一个user-service,它只需要配置好discovery依赖和地址,启动后就会自动注册到 Nacos。
java
// 启动类
@SpringBootApplication
@EnableDiscoveryClient // 开启服务发现(Spring Cloud Alibaba 中通常可省略,自动生效)
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
启动后,在 Nacos 控制台的"服务管理" -> "服务列表"中,你应该能看到 user-service。
- 服务消费者
消费者通过DiscoveryClient或RestTemplate来调用提供者。
java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@RestController
public class ConsumerController {
@Autowired
private DiscoveryClient discoveryClient;
@Autowired
private RestTemplate restTemplate;
@GetMapping("/call-user")
public String callUserService() {
// 1. 从 Nacos 获取名为 "user-service" 的所有实例
List<ServiceInstance> instances = discoveryClient.getInstances("user-service");
if (instances.isEmpty()) {
return "没有找到可用的用户服务";
}
// 2. 获取第一个实例的地址
ServiceInstance instance = instances.get(0);
String url = instance.getUri() + "/user/info"; // 假设提供者有这个接口
// 3. 发起调用
return "调用结果: " + restTemplate.getForObject(url, String.class);
}
}
常见坑点与排查
- 配置无法加载 :
- 检查
bootstrap.yml是否写错成了application.yml。 - 检查 Nacos 中的 Data ID 是否与代码中的
spring.application.name完全一致。 - 检查
file-extension是否匹配(如 Nacos 中是.yaml,配置里也要写yaml)。
- 检查
- 服务注册不上 :
- 检查 Nacos 服务端是否真的启动成功(查看日志)。
- 检查
server-addr端口是否被防火墙拦截。 - 如果是 Docker 环境,注意 IP 地址的映射问题。
- 动态刷新不生效 :
- 确保类上加了
@RefreshScope注解。 - 确保引入了
spring-boot-starter-actuator依赖。
- 确保类上加了
通过以上步骤,你已经成功将 Nacos 集成到了 Spring Boot 3.x 项目中,实现了微服务架构中最核心的注册与配置功能。