本文详解Nacos的部署配置与实战应用,实现微服务的服务发现和统一配置管理。
前言
微服务架构的两大核心问题:
- 服务发现:服务实例动态变化,如何找到对方?
- 配置管理:配置分散各处,如何统一管理?
Nacos是阿里开源的服务发现和配置管理平台:
- 支持服务注册与发现
- 支持动态配置管理
- 支持DNS和HTTP服务发现
- 支持多环境配置隔离
一、Nacos简介
1.1 核心功能
css
┌─────────────────────────────────────────────────────────┐
│ Nacos │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 服务注册与发现 │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │Service A│ │Service B│ │Service C│ │ │
│ │ │ 实例1 │ │ 实例1 │ │ 实例1 │ │ │
│ │ │ 实例2 │ │ 实例2 │ │ 实例2 │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 配置管理中心 │ │
│ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ │ │
│ │ │ dev配置 │ │ test配置 │ │ prod配置 │ │ │
│ │ └───────────┘ └───────────┘ └───────────┘ │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
1.2 与其他组件对比
| 功能 | Nacos | Eureka | Consul | Zookeeper |
|---|---|---|---|---|
| 服务发现 | ✅ | ✅ | ✅ | ✅ |
| 配置管理 | ✅ | ❌ | ✅ | ❌ |
| 一致性协议 | AP/CP | AP | CP | CP |
| 健康检查 | TCP/HTTP | 心跳 | TCP/HTTP | 心跳 |
| 管理界面 | ✅ | ✅ | ✅ | ❌ |
1.3 数据模型
vbnet
Namespace(命名空间)
└── Group(分组)
└── Service(服务)
└── Cluster(集群)
└── Instance(实例)
配置:
Namespace → Group → DataId
二、安装部署
2.1 单机部署(Docker)
bash
# 启动Nacos
docker run -d --name nacos \
-e MODE=standalone \
-e NACOS_AUTH_ENABLE=true \
-e NACOS_AUTH_TOKEN=SecretKey012345678901234567890123456789012345678901234567890123456789 \
-e NACOS_AUTH_IDENTITY_KEY=nacos \
-e NACOS_AUTH_IDENTITY_VALUE=nacos \
-p 8848:8848 \
-p 9848:9848 \
-p 9849:9849 \
nacos/nacos-server:v2.3.0
# 访问控制台
# http://localhost:8848/nacos
# 用户名/密码:nacos/nacos
2.2 Docker Compose部署
yaml
# docker-compose.yml
version: '3.8'
services:
nacos:
image: nacos/nacos-server:v2.3.0
container_name: nacos
environment:
- MODE=standalone
- SPRING_DATASOURCE_PLATFORM=mysql
- MYSQL_SERVICE_HOST=mysql
- MYSQL_SERVICE_PORT=3306
- MYSQL_SERVICE_DB_NAME=nacos
- MYSQL_SERVICE_USER=nacos
- MYSQL_SERVICE_PASSWORD=nacos123
- NACOS_AUTH_ENABLE=true
- NACOS_AUTH_TOKEN=SecretKey012345678901234567890123456789012345678901234567890123456789
- NACOS_AUTH_IDENTITY_KEY=nacos
- NACOS_AUTH_IDENTITY_VALUE=nacos
ports:
- "8848:8848"
- "9848:9848"
- "9849:9849"
depends_on:
- mysql
restart: unless-stopped
mysql:
image: mysql:8.0
container_name: nacos-mysql
environment:
- MYSQL_ROOT_PASSWORD=root123
- MYSQL_DATABASE=nacos
- MYSQL_USER=nacos
- MYSQL_PASSWORD=nacos123
volumes:
- mysql_data:/var/lib/mysql
- ./mysql-schema.sql:/docker-entrypoint-initdb.d/mysql-schema.sql
ports:
- "3306:3306"
restart: unless-stopped
volumes:
mysql_data:
bash
# 下载初始化SQL
wget https://raw.githubusercontent.com/alibaba/nacos/develop/distribution/conf/mysql-schema.sql
# 启动
docker compose up -d
2.3 集群部署
yaml
# docker-compose-cluster.yml
version: '3.8'
services:
nacos1:
image: nacos/nacos-server:v2.3.0
hostname: nacos1
environment:
- MODE=cluster
- NACOS_SERVERS=nacos1:8848 nacos2:8848 nacos3:8848
- SPRING_DATASOURCE_PLATFORM=mysql
- MYSQL_SERVICE_HOST=mysql
- MYSQL_SERVICE_DB_NAME=nacos
- MYSQL_SERVICE_USER=nacos
- MYSQL_SERVICE_PASSWORD=nacos123
- NACOS_AUTH_ENABLE=true
- NACOS_AUTH_TOKEN=SecretKey012345678901234567890123456789012345678901234567890123456789
ports:
- "8848:8848"
nacos2:
image: nacos/nacos-server:v2.3.0
hostname: nacos2
environment:
- MODE=cluster
- NACOS_SERVERS=nacos1:8848 nacos2:8848 nacos3:8848
- SPRING_DATASOURCE_PLATFORM=mysql
- MYSQL_SERVICE_HOST=mysql
- MYSQL_SERVICE_DB_NAME=nacos
- MYSQL_SERVICE_USER=nacos
- MYSQL_SERVICE_PASSWORD=nacos123
- NACOS_AUTH_ENABLE=true
- NACOS_AUTH_TOKEN=SecretKey012345678901234567890123456789012345678901234567890123456789
ports:
- "8849:8848"
nacos3:
image: nacos/nacos-server:v2.3.0
hostname: nacos3
environment:
- MODE=cluster
- NACOS_SERVERS=nacos1:8848 nacos2:8848 nacos3:8848
- SPRING_DATASOURCE_PLATFORM=mysql
- MYSQL_SERVICE_HOST=mysql
- MYSQL_SERVICE_DB_NAME=nacos
- MYSQL_SERVICE_USER=nacos
- MYSQL_SERVICE_PASSWORD=nacos123
- NACOS_AUTH_ENABLE=true
- NACOS_AUTH_TOKEN=SecretKey012345678901234567890123456789012345678901234567890123456789
ports:
- "8850:8848"
三、服务注册与发现
3.1 Spring Cloud集成
添加依赖:
xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2022.0.0.0</version>
</dependency>
配置:
yaml
# application.yml
spring:
application:
name: user-service
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
namespace: public
group: DEFAULT_GROUP
username: nacos
password: nacos
启用服务发现:
java
@SpringBootApplication
@EnableDiscoveryClient
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
3.2 服务调用
java
// 使用LoadBalancer
@Configuration
public class RestTemplateConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
// 调用服务
@Service
public class OrderService {
@Autowired
private RestTemplate restTemplate;
public User getUser(Long userId) {
// 直接使用服务名
return restTemplate.getForObject(
"http://user-service/users/" + userId,
User.class
);
}
}
3.3 OpenFeign调用
java
@FeignClient(name = "user-service")
public interface UserClient {
@GetMapping("/users/{id}")
User getUser(@PathVariable("id") Long id);
}
四、配置管理
4.1 集成配置中心
添加依赖:
xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2022.0.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
配置:
yaml
# bootstrap.yml
spring:
application:
name: user-service
profiles:
active: dev
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
file-extension: yaml
namespace: public
group: DEFAULT_GROUP
username: nacos
password: nacos
4.2 在Nacos创建配置
yaml
Data ID: user-service-dev.yaml
Group: DEFAULT_GROUP
配置格式: YAML
配置内容:
server:
port: 8080
app:
name: 用户服务
version: 1.0.0
database:
url: jdbc:mysql://localhost:3306/users
username: root
password: 123456
4.3 读取配置
java
@RestController
@RefreshScope // 支持动态刷新
public class ConfigController {
@Value("${app.name}")
private String appName;
@Value("${app.version}")
private String appVersion;
@GetMapping("/config")
public Map<String, String> getConfig() {
Map<String, String> config = new HashMap<>();
config.put("appName", appName);
config.put("appVersion", appVersion);
return config;
}
}
4.4 配置监听
java
@Component
public class ConfigListener implements ApplicationListener<NacosConfigReceivedEvent> {
@Override
public void onApplicationEvent(NacosConfigReceivedEvent event) {
System.out.println("配置变更: " + event.getDataId());
// 处理配置变更逻辑
}
}
五、多环境配置
5.1 命名空间隔离
sql
命名空间规划:
├── dev(开发环境)
│ └── user-service-dev.yaml
├── test(测试环境)
│ └── user-service-test.yaml
└── prod(生产环境)
└── user-service-prod.yaml
yaml
# bootstrap-dev.yml
spring:
cloud:
nacos:
config:
namespace: dev-namespace-id
# bootstrap-prod.yml
spring:
cloud:
nacos:
config:
namespace: prod-namespace-id
5.2 分组隔离
yaml
# 不同项目使用不同Group
spring:
cloud:
nacos:
config:
group: PROJECT_A
5.3 共享配置
yaml
spring:
cloud:
nacos:
config:
shared-configs:
- data-id: common.yaml
group: DEFAULT_GROUP
refresh: true
extension-configs:
- data-id: database.yaml
group: DEFAULT_GROUP
refresh: true
六、多站点部署
6.1 场景
diff
企业多机房部署:
- 总部机房:Nacos集群 + 服务A、B、C
- 分部机房:Nacos集群 + 服务D、E、F
- 需要跨机房服务调用
6.2 组网方案
使用组网软件(如星空组网)打通多机房网络:
yaml
┌───────────────────────────────────────────────────────────┐
│ 组网虚拟局域网 │
│ │
│ ┌────────────────────┐ ┌────────────────────┐ │
│ │ 总部机房 │ │ 分部机房 │ │
│ │ │ │ │ │
│ │ Nacos: 10.10.0.1 │ │ Nacos: 10.10.0.10│ │
│ │ ServiceA:10.10.0.2│ │ ServiceD:10.10.0.11│ │
│ │ ServiceB:10.10.0.3│ │ ServiceE:10.10.0.12│ │
│ │ │ │ │ │
│ └────────────────────┘ └────────────────────┘ │
│ ↑ ↑ │
│ └─────────┬───────────────┘ │
│ │ │
│ 跨机房服务调用 │
└───────────────────────────────────────────────────────────┘
配置方式:
yaml
# 总部服务配置
spring:
cloud:
nacos:
discovery:
server-addr: 10.10.0.1:8848 # 组网IP
config:
server-addr: 10.10.0.1:8848
# 分部服务配置
spring:
cloud:
nacos:
discovery:
server-addr: 10.10.0.10:8848 # 组网IP
config:
server-addr: 10.10.0.10:8848
6.3 Nacos集群同步
yaml
# 配置两个Nacos集群数据同步
# 使用Nacos的集群同步功能或配置复制
效果:
- 各机房服务正常注册发现
- 跨机房服务可相互调用
- 配置统一管理
- 网络安全加密
七、运维管理
7.1 健康检查
bash
# API健康检查
curl http://localhost:8848/nacos/v1/console/health/readiness
# 集群状态
curl http://localhost:8848/nacos/v1/core/cluster/nodes
7.2 监控指标
yaml
# prometheus配置
scrape_configs:
- job_name: 'nacos'
metrics_path: '/nacos/actuator/prometheus'
static_configs:
- targets: ['nacos:8848']
7.3 数据备份
bash
# 导出配置
curl -X GET "http://localhost:8848/nacos/v1/cs/configs?export=true&tenant=&group=DEFAULT_GROUP" \
-H "Authorization: Bearer token" \
-o nacos_config_backup.zip
# 导入配置
curl -X POST "http://localhost:8848/nacos/v1/cs/configs?import=true" \
-H "Authorization: Bearer token" \
-F "file=@nacos_config_backup.zip"
7.4 常见问题
服务注册失败:
bash
# 检查网络连通性
telnet nacos-server 8848
telnet nacos-server 9848 # gRPC端口
# 检查认证配置
配置不生效:
java
// 确保添加@RefreshScope
@RefreshScope
@RestController
public class ConfigController {
// ...
}
八、总结
Nacos使用要点:
- 部署方式:生产环境使用集群+MySQL
- 服务发现:Spring Cloud Alibaba集成
- 配置管理:多环境命名空间隔离
- 动态刷新:@RefreshScope注解
- 多机房:组网打通后统一注册
- 安全:启用认证,配置鉴权
最佳实践:
☑ 生产环境集群部署(至少3节点)
☑ 使用MySQL持久化
☑ 启用认证鉴权
☑ 命名空间环境隔离
☑ 配置定期备份
☑ 监控告警配置
参考资料
- Nacos官方文档:nacos.io/docs/latest...
- Nacos GitHub:github.com/alibaba/nac...
- Spring Cloud Alibaba:sca.aliyun.com/docs/2023/
💡 建议:先在开发环境单机部署熟悉,生产环境务必集群+MySQL持久化。