Nacos:服务注册发现与配置管理一体

FreeGuideOnline 最新 2026-06-30

bash wget https://github.com/alibaba/nacos/releases/download/2.2.3/nacos-server-2.2.3.zip unzip nacos-server-2.2.3.zip cd nacos/bin


### 2.3 单机启动
- **Linux/Unix/Mac**:
  ```bash
  sh startup.sh -m standalone
  • Windows
    startup.cmd -m standalone
    

启动后访问:http://127.0.0.1:8848/nacos
默认账号/密码:nacos/nacos

看到登录界面即代表启动成功。8848 是 Nacos 默认端口,取自珠峰高度,很有辨识度。

3. 服务注册与发现快速实践

我们使用 Spring Boot 工程来演示服务提供者和服务消费者的注册与发现。
整体步骤:引入依赖 → 配置注册中心地址 → 启动类加注解 → 服务调用。

3.1 服务提供者 (Provider)

创建一个 Spring Boot 项目,添加 Spring Web 和 Nacos Discovery 依赖。

Maven 依赖核心片段

<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>

application.yml 配置

server:
  port: 8081
spring:
  application:
    name: demo-provider    # 服务名,很重要
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848   # Nacos 服务地址

启动类

@SpringBootApplication
@EnableDiscoveryClient   // 开启服务发现客户端
public class ProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProviderApplication.class, args);
    }
}

编写一个简单的 REST 接口,用于后续消费者调用:

@RestController
public class EchoController {
    @GetMapping("/echo/{message}")
    public String echo(@PathVariable String message) {
        return "Hello Nacos Discovery: " + message;
    }
}

启动提供者应用,登录 Nacos 控制台,在服务管理 → 服务列表中可以看到 demo-provider 服务已成功注册,健康实例数为 1。

3.2 服务消费者 (Consumer)

同样新建 Spring Boot 项目,引入相同的 Nacos Discovery 依赖和 Web 依赖,另外需要引入 spring-cloud-starter-loadbalancer 以实现服务调用时的负载均衡。

Maven 额外依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

application.yml

server:
  port: 8082
spring:
  application:
    name: demo-consumer
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

启动类也添加 @EnableDiscoveryClient

配置 RestTemplate,并标注 @LoadBalanced 使它能通过服务名调用:

@Configuration
public class RestTemplateConfig {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

消费者测试接口,直接通过服务名调用提供者的 /echo 接口:

@RestController
public class ConsumerController {
    @Autowired
    private RestTemplate restTemplate;
    
    @GetMapping("/consumer/echo/{msg}")
    public String echo(@PathVariable String msg) {
        // 地址中 demo-provider 就是服务提供者的 spring.application.name
        return restTemplate.getForObject("http://demo-provider/echo/" + msg, String.class);
    }
}

启动消费者,访问 http://localhost:8082/consumer/echo/nacos,返回 Hello Nacos Discovery: nacos,说明服务发现与调用成功。
Nacos 控制台的订阅者列表中也能看到消费者信息。

3.3 服务健康检查与保护

Nacos 支持临时实例和永久实例。默认的 Spring Cloud 集成使用临时实例,通过客户端主动上报心跳(5秒一次)来维持健康状态。若掉线 15 秒未心跳,则实例被标记为不健康;30 秒未恢复则剔除。
你可以在控制台手动上下线实例,或配置保护阈值(0-1之间),当健康实例数占总实例数比例小于该阈值时,消费端会继续访问所有实例(包括不健康的),防止雪崩。

4. 配置管理快速实践

Nacos 的配置中心支持动态刷新,可实时生效,无需重启应用。下面演示如何从 Nacos 读取配置并实现动态更新。

4.1 添加依赖

在 Spring Boot 项目中同时引入配置中心依赖(一般与 Discovery 一起使用):

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

4.2 配置引导文件 bootstrap.yml

Nacos Config 需要在应用启动早期加载,因此推荐使用 bootstrap.ymlbootstrap.properties

spring:
  application:
    name: demo-config          # 必须与 Nacos 中的 Data Id 前缀匹配
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
        file-extension: yaml    # 指定配置格式,支持 properties/yaml

注意:Spring Boot 2.4+ 需要额外添加依赖 spring-cloud-starter-bootstrap 才能使 bootstrap.yml 生效,或者直接在 application.yml 中使用 spring.config.import 方式,这里仍以传统方式为例。

4.3 在 Nacos 控制台添加配置

进入配置管理 → 配置列表,点击右侧+新建配置:

  • Data ID: demo-config.yaml (命名规则:${spring.application.name}.${file-extension}
  • Group: DEFAULT_GROUP
  • 配置内容
    user:
      name: Nacos
      age: 20
    

4.4 读取配置并实现动态刷新

创建测试 Controller,使用 @RefreshScope 注解使配置更改后实时生效:

@RestController
@RefreshScope   // 开启配置动态刷新
public class ConfigController {
    @Value("${user.name}")
    private String userName;
    
    @Value("${user.age}")
    private int age;
    
    @GetMapping("/config")
    public String getConfig() {
        return "User: " + userName + ", Age: " + age;
    }
}