Spring Cloud Alibaba Nacos 服务注册发现和分布式配置中心
-
-
- [一、 版本适配(关键)](#一、 版本适配(关键))
- [二、 Nacos 服务端部署](#二、 Nacos 服务端部署)
-
- [1. 单机模式(开发/测试环境)](#1. 单机模式(开发/测试环境))
- [2. 生产环境部署(简化版)](#2. 生产环境部署(简化版))
- [三、 Spring Boot 项目整合](#三、 Spring Boot 项目整合)
-
- [1. 添加依赖 (pom.xml)](#1. 添加依赖 (pom.xml))
- [2. 配置文件 (application.yml)](#2. 配置文件 (application.yml))
- [3. 启动类注解](#3. 启动类注解)
- [四、 核心功能使用演示](#四、 核心功能使用演示)
-
- [1. 动态配置中心 (Config)](#1. 动态配置中心 (Config))
- [2. 服务注册与发现 (Discovery)](#2. 服务注册与发现 (Discovery))
- [五、 常见排坑指南](#五、 常见排坑指南)
-
一、 版本适配(关键)
版本不匹配是新手最容易踩的坑,请严格遵守以下对应关系:
| Spring Cloud Alibaba | Spring Cloud | Spring Boot | Nacos Server 推荐版本 |
|---|---|---|---|
| 2023.0.1.0 | 2023.0.x | 3.2.x | 2.3.2 |
| 2022.0.0.0 | 2022.0.x | 3.0.x | 2.2.1 |
| 2021.0.5.0 | 2021.0.x | 2.6.x | 2.2.0 |
建议 :新项目直接使用 Spring Boot 3.2.x + SCA 2023.0.1.0 + Nacos 2.3.2。
二、 Nacos 服务端部署
推荐使用 Docker 部署,方便快捷。
1. 单机模式(开发/测试环境)
最简单的部署方式,使用内置 Derby 数据库(无需安装 MySQL)。
Docker 命令:
Bash
docker run -d \
--name nacos-standalone \
-e MODE=standalone \
-p 8848:8848 \
-p 9848:9848 \
nacos/nacos-server:v2.3.2
- 访问控制台 :
http://localhost:8848/nacos - 默认账号/密码 :
nacos/nacos
2. 生产环境部署(简化版)
生产环境必须使用 MySQL 作为持久化存储,并建议开启鉴权。
docker-compose.yml 示例:
YAML
version: "3.8"
services:
nacos:
image: nacos/nacos-server:v2.3.2
container_name: nacos-prod
environment:
- MODE=standalone # 这里的standalone指单节点,但开启MySQL存储
- SPRING_DATASOURCE_PLATFORM=mysql
- MYSQL_SERVICE_HOST=mysql-host # 你的MySQL地址
- MYSQL_SERVICE_PORT=3306
- MYSQL_SERVICE_DB_NAME=nacos
- MYSQL_SERVICE_USER=nacos_user
- MYSQL_SERVICE_PASSWORD=nacos_pwd
- NACOS_AUTH_ENABLE=true # 开启鉴权
- NACOS_AUTH_TOKEN=SecretKey012345678901234567890123456789012345678901234567890123456789 # 务必修改此密钥
ports:
- "8848:8848"
- "9848:9848"
注意 :在使用 MySQL 模式前,需在数据库中执行 Nacos 提供的 mysql-schema.sql 初始化表结构。
三、 Spring Boot 项目整合
假设我们创建一个服务提供者 service-provider。
1. 添加依赖 (pom.xml)
在 <dependencies> 中添加 Nacos 发现和配置依赖。
XML
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2023.0.1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2023.0.0</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-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
</dependencies>
2. 配置文件 (application.yml)
Spring Boot 2.4+ 推荐使用 spring.config.import 方式引入 Nacos 配置,不再强制依赖 bootstrap.yml。
YAML
server:
port: 8080
spring:
application:
name: service-provider
profiles:
active: dev
cloud:
nacos:
server-addr: localhost:8848 # Nacos 服务端地址
username: nacos
password: nacos
discovery:
group: DEFAULT_GROUP
config:
file-extension: yaml # 指定配置文件后缀
# 关键配置:导入 Nacos 配置中心的文件
config:
import:
- optional:nacos:${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
3. 启动类注解
虽然现在的版本通常自动生效,但显式添加注解是个好习惯。
Java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient // 开启服务发现
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
四、 核心功能使用演示
1. 动态配置中心 (Config)
场景:不重启服务修改配置。
-
在 Nacos 控制台新建配置:
-
Data ID :
service-provider-dev.yaml(格式:应用名-环境.扩展名) -
Group :
DEFAULT_GROUP -
配置内容:
YAML
user: name: "Gemini User" age: 18
-
-
代码中使用
@RefreshScope实现热更新: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 // 核心注解:配置变更时自动刷新 Bean public class ConfigController { @Value("${user.name:Default}") private String userName; @GetMapping("/config") public String getConfig() { return "Current User: " + userName; } } -
测试 :调用接口,然后在 Nacos 控制台修改
user.name并发布,再次调用接口,值会立即改变。
2. 服务注册与发现 (Discovery)
场景:服务 A (Consumer) 调用 服务 B (Provider)。
-
启动 Provider (端口 8080)。
-
启动 Consumer (端口 8081),配置同上,只需修改
spring.application.name。 -
Consumer 调用 Provider (使用 RestClient 或 OpenFeign):
- Spring Boot 3.x 推荐使用 OpenFeign 或 RestClient。
使用 OpenFeign 示例:
- 引入
spring-cloud-starter-openfeign依赖。 - 启动类加
@EnableFeignClients。
Java
@FeignClient(name = "service-provider") // 指定目标服务名 public interface UserClient { @GetMapping("/config") String getUserConfig(); }
五、 常见排坑指南
- 错误:Client not connected, currentServerAddr...
- 原因:Nacos 2.x 增加了 gRPC 通信端口。
- 解决 :确保防火墙同时开放了
8848(主端口) 和9848(gRPC端口)。Docker 映射时也要同时映射这两个端口。
- 错误:No spring.config.import set
- 原因 :Spring Boot 2.4+ 必须配置 import 或者添加
spring-cloud-starter-bootstrap依赖使用旧版 bootstrap.yml 模式。 - 解决 :推荐使用
spring.config.import: optional:nacos:...方式。
- 原因 :Spring Boot 2.4+ 必须配置 import 或者添加
- 多环境隔离
- 使用 Namespace (命名空间) 来隔离环境(如 Dev, Test, Prod)。不要用 Group 来做环境隔离。在
application.yml中配置namespace: <Namespace-ID>即可。
- 使用 Namespace (命名空间) 来隔离环境(如 Dev, Test, Prod)。不要用 Group 来做环境隔离。在