Skip to content

Nacos 使用指南 ​

Nacos 是阿里巴巴开源的服务注册、发现和配置管理平台。

一、服务注册与发现 ​

Dubbo 集成(推荐) ​

Dubbo 原生集成 Nacos 作为注册中心,使用 @EnableDubbo 即可同时启用服务注册与发现。

Maven 依赖 ​

xml
<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-nacos-spring-boot-starter</artifactId>
</dependency>

版本由 dubbo-dependencies-bom 统一管理,推荐 3.3.6。

application.yml(Provider) ​

yaml
spring:
  application:
    name: user-service

dubbo:
  application:
    name: ${spring.application.name}
  protocol:
    name: dubbo          # dubbo / tri(gRPC 兼容)
    port: 20880          # -1 = 自动分配端口
  registry:
    address: nacos://127.0.0.1:8848
    parameters:
      namespace: dev     # Nacos 命名空间 ID
      group: DEFAULT_GROUP

定义服务接口(公共 api 模块) ​

java
// 放在独立的 api 模块中,Provider 和 Consumer 共同依赖
public interface UserService {
    UserDTO getById(Long id);
    Result<Long> create(UserCreateCmd cmd);
    List<UserDTO> listByCondition(UserQuery query);
}

Provider(提供者) ​

java
@DubboService
public class UserServiceImpl implements UserService {

    @Override
    public UserDTO getById(Long id) {
        return userMapper.selectById(id);
    }

    @Override
    public Result<Long> create(UserCreateCmd cmd) {
        // 业务逻辑
        return Result.success(userId);
    }
}

// 启动类
@EnableDubbo
@SpringBootApplication
public class UserServiceApplication { }

Consumer(消费者) ​

java
@RestController
public class OrderController {

    @DubboReference
    private UserService userService;

    @PostMapping("/orders")
    public Result<Long> createOrder(@RequestBody OrderCmd cmd) {
        UserDTO user = userService.getById(cmd.getUserId());
        // 处理订单逻辑
        return Result.success(orderId);
    }
}

// 启动类
@EnableDubbo
@SpringBootApplication
public class OrderApplication { }

@DubboService 参数 ​

参数说明默认值
version服务版本号—
group服务分组—
timeout超时时间 ms1000
retries重试次数2
loadbalance负载均衡策略random
weight服务权重100
cluster集群容错策略failover
executes并发请求上限—
delay延迟暴露 ms0

@DubboReference 参数 ​

参数说明默认值
version目标服务版本—
group目标服务分组—
timeout超时时间 ms1000
retries重试次数2
loadbalance负载均衡策略random
cluster集群容错策略failover
check启动时检查提供者true
async异步调用false
lazy延迟连接false
injvm优先本地调用true

负载均衡策略 ​

策略说明
random按权重随机(默认)
roundrobin按权重轮询
leastactive最少活跃调用数
consistenthash一致性 Hash
shortestresponse最短响应时间

集群容错策略 ​

策略说明
failover失败自动重试其他节点(默认)
failfast快速失败,立即抛异常
failsafe忽略异常,记录日志
failback失败后后台定时重试
forking并行调用多节点取第一个成功
broadcast广播调用所有节点

版本与分组 ​

java
// Provider 发布不同版本
@DubboService(version = "1.0.0", group = "stable")
public class UserServiceImplV1 implements UserService { }

@DubboService(version = "2.0.0", group = "beta")
public class UserServiceImplV2 implements UserService { }

// Consumer 指定版本
@DubboReference(version = "1.0.0", group = "stable")
private UserService userService;

异步调用 ​

java
@DubboReference(async = true)
private UserService userService;

public void process() {
    userService.getById(1001L);  // 立即返回
    FutureAdapter<UserDTO> future = RpcContext.getServiceContext().getFuture();
    // 执行其他操作...
    UserDTO result = future.get();  // 阻塞获取结果
}

二、配置中心 ​

适用版本:Spring Boot 2.7.x + Spring Cloud 2021.0.x + Spring Cloud Alibaba 2021.0.x

Docker 部署 Nacos Server ​

单机模式(开发/测试环境) ​

bash
docker run -d \
  --name nacos \
  -e MODE=standalone \
  -e NACOS_AUTH_ENABLE=true \
  -e NACOS_AUTH_TOKEN=SecretKey012345678901234567890123456789012345678901234567890123456789 \
  -e NACOS_AUTH_IDENTITY_KEY=serverIdentity \
  -e NACOS_AUTH_IDENTITY_VALUE=security \
  -p 8848:8848 \
  -p 9848:9848 \
  nacos/nacos-server:v2.3.2

端口说明

  • 8848:HTTP 主端口(控制台 + 配置 API)
  • 9848:gRPC 端口(客户端长连接,必须暴露,否则配置推送和监听失效)
  • 9849:gRPC 集群通信端口(单机可不暴露)

常见坑点

从 Nacos 2.x 开始,客户端通过 gRPC(9848 端口)与服务端通信。如果 Docker 只映射了 8848 而没映射 9848,会导致:

  • 配置获取超时
  • 服务注册成功但配置拉不到
  • NacosException: Client not connected 错误

Docker Compose 方式 ​

yaml
# docker-compose.yml
version: '3.8'
services:
  nacos:
    image: nacos/nacos-server:v2.3.2
    container_name: nacos
    environment:
      - MODE=standalone
      - NACOS_AUTH_ENABLE=true
      - NACOS_AUTH_TOKEN=SecretKey012345678901234567890123456789012345678901234567890123456789
      - NACOS_AUTH_IDENTITY_KEY=serverIdentity
      - NACOS_AUTH_IDENTITY_VALUE=security
      - JVM_XMS=256m
      - JVM_XMX=256m
      - JVM_XMN=128m
    ports:
      - "8848:8848"
      - "9848:9848"
    volumes:
      - nacos-logs:/home/nacos/logs
    restart: unless-stopped

volumes:
  nacos-logs:
bash
docker-compose up -d

验证 Nacos 是否正常 ​

bash
# 访问控制台
open http://localhost:8848/nacos
# 默认账号密码:nacos / nacos

# API 验证
curl http://localhost:8848/nacos/v1/console/health/readiness

版本对应关系 ​

Spring Boot 2.7.x 对应的版本矩阵:

组件版本
Spring Boot2.7.x
Spring Cloud2021.0.x
Spring Cloud Alibaba2021.0.x
Nacos Server2.x(推荐 2.3.x)

版本不匹配是配置获取失败的头号原因

Spring Cloud Alibaba 版本必须与 Spring Boot 版本匹配,否则自动配置类不会生效,配置静默拉取失败。

Maven 依赖(完整) ​

父 POM 依赖管理 ​

xml
<properties>
    <spring-boot.version>2.7.18</spring-boot.version>
    <spring-cloud.version>2021.0.9</spring-cloud.version>
    <spring-cloud-alibaba.version>2021.0.6.0</spring-cloud-alibaba.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>${spring-cloud-alibaba.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

子模块依赖 ​

xml
<dependencies>
    <!-- Nacos 配置中心 -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>

    <!-- Bootstrap 上下文支持(Spring Boot 2.4+ 必须显式引入) -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-bootstrap</artifactId>
    </dependency>

    <!-- Web(示例用) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

spring-cloud-starter-bootstrap 是关键

Spring Boot 2.4 之后默认不再加载 bootstrap.yml。如果不引入 spring-cloud-starter-bootstrap,bootstrap.yml 中的 Nacos 配置不会生效,导致应用启动时无法连接配置中心。

这是 Spring Boot 2.7.x 获取不到 Nacos 配置最常见的原因之一。

配置文件编写 ​

方式一:bootstrap.yml(推荐,传统方式) ​

Spring Boot 2.7.x 下推荐使用此方式。

yaml
# src/main/resources/bootstrap.yml
spring:
  application:
    name: order-service
  profiles:
    active: dev
  cloud:
    nacos:
      # Nacos 服务端地址
      server-addr: 127.0.0.1:8848
      # 认证信息(Nacos 开启鉴权时必须配置)
      username: nacos
      password: nacos
      # ---- 配置中心 ----
      config:
        # 配置文件格式
        file-extension: yaml
        # 命名空间 ID(注意:是 ID,不是名称)
        namespace: public
        # 分组
        group: DEFAULT_GROUP
        # 是否开启配置刷新
        refresh-enabled: true
        # 共享配置(多个服务共用的配置)
        shared-configs:
          - data-id: common.yaml
            group: DEFAULT_GROUP
            refresh: true
        # 扩展配置(优先级高于主配置)
        extension-configs:
          - data-id: db.yaml
            group: DATABASE_GROUP
            refresh: true
yaml
# src/main/resources/bootstrap-dev.yml
spring:
  cloud:
    nacos:
      config:
        # dev 环境的命名空间 ID(从 Nacos 控制台复制)
        namespace: e5a3b1c0-xxxx-xxxx-xxxx-xxxxxxxxxxxx

方式二:application.yml(Spring Boot 2.4+ 新方式) ​

不依赖 bootstrap,直接在 application.yml 中使用 spring.config.import:

yaml
# src/main/resources/application.yml
spring:
  application:
    name: order-service
  cloud:
    nacos:
      server-addr: 127.0.0.1:8848
      username: nacos
      password: nacos
      config:
        namespace: public
        group: DEFAULT_GROUP
  config:
    import:
      - nacos:order-service.yaml?refreshEnabled=true&group=DEFAULT_GROUP
      - nacos:common.yaml?refreshEnabled=true&group=DEFAULT_GROUP

两种方式的对比

特性bootstrap.ymlapplication.yml + import
需要额外依赖需要 spring-cloud-starter-bootstrap不需要
配置优先级高于 application.yml等于 application.yml
多 profile 支持天然支持 bootstrap-dev.yml需要 import 中拼接 profile
Spring Boot 2.7.x 推荐推荐可用
Spring Boot 3.x 推荐不推荐推荐

Nacos 控制台配置 ​

创建配置 ​

登录 Nacos 控制台 http://localhost:8848/nacos:

  1. 进入 配置管理 → 配置列表
  2. 选择对应的 命名空间(dev / test / prod)
  3. 点击 + 号创建配置

Data ID 命名规则:

text
${spring.application.name}-${spring.profiles.active}.${file-extension}

例如 spring.application.name=order-service,spring.profiles.active=dev,file-extension=yaml:

配置项值
Data IDorder-service-dev.yaml
GroupDEFAULT_GROUP
配置格式YAML

配置内容示例:

yaml
# Nacos 控制台中的 order-service-dev.yaml
server:
  port: 8080

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/order_db?useSSL=false&characterEncoding=utf8
    username: root
    password: your-password
    driver-class-name: com.mysql.cj.jdbc.Driver

# 自定义配置
app:
  name: 订单服务
  version: 1.0.0
  features:
    - order-create
    - order-query

配置读取方式 ​

@Value 注入 ​

java
@RestController
@RefreshScope  // 支持 Nacos 动态刷新
public class ConfigDemoController {

    @Value("${app.name:默认应用名}")
    private String appName;

    @Value("${app.version:unknown}")
    private String appVersion;

    @GetMapping("/config")
    public Map<String, String> getConfig() {
        Map<String, String> map = new HashMap<>();
        map.put("appName", appName);
        map.put("appVersion", appVersion);
        return map;
    }
}

@ConfigurationProperties 绑定 ​

java
@Data
@Component
@ConfigurationProperties(prefix = "app")
@RefreshScope
public class AppProperties {
    private String name;
    private String version;
    private List<String> features;
}
java
@RestController
@RequiredArgsConstructor
public class AppConfigController {

    private final AppProperties appProperties;

    @GetMapping("/app-info")
    public AppProperties getAppInfo() {
        return appProperties;
    }
}

@NacosValue 注解(可选) ​

java
@RestController
public class NacosValueController {

    @NacosValue(value = "${app.name:默认}", autoRefreshed = true)
    private String appName;

    @GetMapping("/nacos-value")
    public String get() {
        return appName;
    }
}

配置优先级(从高到低) ​

text
1. extension-configs(扩展配置,序号越大优先级越高)
2. shared-configs(共享配置,序号越大优先级越高)
3. ${spring.application.name}-${spring.profiles.active}.${file-extension}
4. ${spring.application.name}.${file-extension}
5. 本地 application.yml / application-dev.yml

动态刷新(@RefreshScope) ​

在 Nacos 控制台修改配置并发布后,使用 @RefreshScope 标注的 Bean 会自动刷新:

java
@RefreshScope
@RestController
public class DynamicConfigController {

    @Value("${app.greeting:Hello}")
    private String greeting;

    @GetMapping("/greeting")
    public String get() {
        return greeting + " " + LocalDateTime.now();
    }
}

验证动态刷新

  1. 修改 Nacos 中的 app.greeting 值并发布
  2. 再次调用 /greeting 接口
  3. 观察返回值是否变化

配置获取失败排查清单 ​

以下是 Docker 部署 Nacos 后,Spring Boot 应用获取不到配置的常见原因和排查步骤:

1. 检查端口映射 ​

bash
# 确认 8848 和 9848 都已映射
docker port nacos
# 期望输出:
# 8848/tcp -> 0.0.0.0:8848
# 9848/tcp -> 0.0.0.0:9848

如果缺少 9848 映射,配置推送和长连接监听全部失效。

2. 检查网络连通性 ​

bash
# 从应用所在机器访问 Nacos
curl http://127.0.0.1:8848/nacos/v1/console/health/readiness

# 检查 gRPC 端口
telnet 127.0.0.1 9848

Docker 网络注意

如果应用也在 Docker 中运行,server-addr 不能写 127.0.0.1,需要使用 Docker 网络中的容器名或宿主机 IP:

yaml
spring:
  cloud:
    nacos:
      server-addr: nacos:8848  # Docker Compose 中使用服务名

3. 检查 namespace 是否为 ID ​

yaml
spring:
  cloud:
    nacos:
      config:
        # 错误:使用了命名空间名称
        namespace: dev
        # 正确:使用命名空间 ID(从 Nacos 控制台 → 命名空间 页面复制)
        namespace: e5a3b1c0-xxxx-xxxx-xxxx-xxxxxxxxxxxx

namespace 必须用 ID

namespace 的值必须是 Nacos 控制台 命名空间 页面中显示的 命名空间 ID(UUID 格式),而不是命名空间名称。public 是唯一的例外,可以直接写 public 或留空。

4. 检查 Data ID 是否匹配 ​

启动日志中查找实际请求的 Data ID:

text
# 启动日志中搜索这行
[fixed-DEFAULT_GROUP] data received, dataId=order-service-dev.yaml, group=DEFAULT_GROUP

确保 Nacos 控制台中存在的 Data ID 与应用自动拼接的完全一致:

text
Data ID = ${spring.application.name}[-${spring.profiles.active}].${file-extension}
场景Data ID
name=order-service, profile=dev, ext=yamlorder-service-dev.yaml
name=order-service, 无 profile, ext=yamlorder-service.yaml
name=order-service, profile=dev, ext=propertiesorder-service-dev.properties

5. 检查鉴权配置 ​

如果 Nacos 开启了鉴权(NACOS_AUTH_ENABLE=true),客户端必须配置用户名密码:

yaml
spring:
  cloud:
    nacos:
      username: nacos
      password: nacos

鉴权不配置的表现

配置中心返回 403,但 Spring Boot 可能静默回退到本地配置,不报错,导致看起来"配置没拉到"。

6. 检查 bootstrap 是否生效 ​

在 application.yml 或启动日志中确认:

text
# 如果看到以下日志,说明 bootstrap 已加载
Located property source: CompositePropertySource {name='NACOS', propertySources=[...]}

如果完全看不到 Nacos 相关日志,说明 bootstrap.yml 没有被加载:

  • 确认引入了 spring-cloud-starter-bootstrap 依赖
  • 确认配置文件名是 bootstrap.yml(不是 bootstrap.yaml,两者都可以,但不要拼错)

7. 开启调试日志 ​

yaml
# application.yml 或 bootstrap.yml 中添加
logging:
  level:
    com.alibaba.nacos: DEBUG
    org.springframework.cloud.nacos: DEBUG

通过日志可以看到完整的配置拉取过程、请求参数和响应结果。

完整可运行示例 ​

项目结构 ​

text
order-service/
├── pom.xml
└── src/main/
    ├── java/com/example/order/
    │   ├── OrderApplication.java
    │   └── controller/
    │       └── ConfigController.java
    └── resources/
        ├── bootstrap.yml
        └── application.yml

pom.xml(关键部分) ​

xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.18</version>
</parent>

<properties>
    <spring-cloud.version>2021.0.9</spring-cloud.version>
    <spring-cloud-alibaba.version>2021.0.6.0</spring-cloud-alibaba.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>${spring-cloud-alibaba.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-bootstrap</artifactId>
    </dependency>
</dependencies>

bootstrap.yml ​

yaml
spring:
  application:
    name: order-service
  profiles:
    active: dev
  cloud:
    nacos:
      server-addr: 127.0.0.1:8848
      username: nacos
      password: nacos
      config:
        file-extension: yaml
        namespace: public
        group: DEFAULT_GROUP

application.yml ​

yaml
server:
  port: 8080

logging:
  level:
    com.alibaba.nacos: DEBUG

OrderApplication.java ​

java
@SpringBootApplication
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
}

ConfigController.java ​

java
@RestController
@RefreshScope
public class ConfigController {

    @Value("${app.name:未获取到配置}")
    private String appName;

    @GetMapping("/config/app-name")
    public String getAppName() {
        return appName;
    }
}

Nacos 控制台操作 ​

  1. 创建配置:Data ID = order-service-dev.yaml,Group = DEFAULT_GROUP
  2. 配置内容:
yaml
app:
  name: 订单服务-v1.0
  1. 发布配置
  2. 启动应用,访问 http://localhost:8080/config/app-name
  3. 期望返回:订单服务-v1.0
最近更新