本文詳解Nacos的部署配置與實戰應用,實現微服務的服務發現和統一配置管理。

前言

微服務架構的兩大核心問題:

  • 服務發現:服務實例動態變化,如何找到對方?
  • 配置管理:配置分散各處,如何統一管理?

Nacos是阿里開源的服務發現和配置管理平台:

  • 支持服務註冊與發現
  • 支持動態配置管理
  • 支持DNS和HTTP服務發現
  • 支持多環境配置隔離

一、Nacos簡介

1.1 核心功能


┌─────────────────────────────────────────────────────────┐
│                        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 數據模型


Namespace(命名空間)
└── Group(分組)
└── Service(服務)
└── Cluster(集羣)
└── Instance(實例)

配置:
Namespace → Group → DataId


二、安裝部署

2.1 單機部署(Docker)

# 啓動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部署

# 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:
# 下載初始化SQL
wget https://raw.githubusercontent.com/alibaba/nacos/develop/distribution/conf/mysql-schema.sql

# 啓動
docker compose up -d

2.3 集羣部署

# 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集成

添加依賴:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>2022.0.0.0</version>
</dependency>

配置:

# 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

啓用服務發現:

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

3.2 服務調用

// 使用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調用

@FeignClient(name = "user-service")
public interface UserClient {
    @GetMapping("/users/{id}")
    User getUser(@PathVariable("id") Long id);
}

四、配置管理

4.1 集成配置中心

添加依賴:

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

配置:

# 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創建配置

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 讀取配置

@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 配置監聽

@Component
public class ConfigListener implements ApplicationListener<NacosConfigReceivedEvent> {
    
    @Override
    public void onApplicationEvent(NacosConfigReceivedEvent event) {
        System.out.println("配置變更: " + event.getDataId());
        // 處理配置變更邏輯
    }
}

五、多環境配置

5.1 命名空間隔離

命名空間規劃:
├── dev(開發環境)
│   └── user-service-dev.yaml
├── test(測試環境)
│   └── user-service-test.yaml
└── prod(生產環境)
    └── user-service-prod.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 分組隔離

# 不同項目使用不同Group
spring:
  cloud:
    nacos:
      config:
        group: PROJECT_A

5.3 共享配置

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

企業多機房部署:
- 總部機房:Nacos集羣 + 服務A、B、C
- 分部機房:Nacos集羣 + 服務D、E、F
- 需要跨機房服務調用

6.2 組網方案

使用組網軟件(如星空組網)打通多機房網絡:

┌───────────────────────────────────────────────────────────┐
│                      組網虛擬局域網                         │
│                                                            │
│  ┌────────────────────┐      ┌────────────────────┐       │
│  │      總部機房       │      │      分部機房       │       │
│  │                    │      │                    │       │
│  │  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│      │
│  │                    │      │                    │       │
│  └────────────────────┘      └────────────────────┘       │
│              ↑                         ↑                   │
│              └─────────┬───────────────┘                   │
│                        │                                   │
│               跨機房服務調用                                │
└───────────────────────────────────────────────────────────┘

配置方式:

# 總部服務配置
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集羣同步

# 配置兩個Nacos集羣數據同步
# 使用Nacos的集羣同步功能或配置複製

效果:

  • 各機房服務正常註冊發現
  • 跨機房服務可相互調用
  • 配置統一管理
  • 網絡安全加密

七、運維管理

7.1 健康檢查

# API健康檢查
curl http://localhost:8848/nacos/v1/console/health/readiness

# 集羣狀態
curl http://localhost:8848/nacos/v1/core/cluster/nodes

7.2 監控指標

# prometheus配置
scrape_configs:
  - job_name: 'nacos'
    metrics_path: '/nacos/actuator/prometheus'
    static_configs:
      - targets: ['nacos:8848']

7.3 數據備份

# 導出配置
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 常見問題

服務註冊失敗:

# 檢查網絡連通性
telnet nacos-server 8848
telnet nacos-server 9848  # gRPC端口

# 檢查認證配置

配置不生效:

// 確保添加@RefreshScope
@RefreshScope
@RestController
public class ConfigController {
    // ...
}

八、總結

Nacos使用要點:

  1. 部署方式:生產環境使用集羣+MySQL
  2. 服務發現:Spring Cloud Alibaba集成
  3. 配置管理:多環境命名空間隔離
  4. 動態刷新:@RefreshScope註解
  5. 多機房:組網打通後統一註冊
  6. 安全:啓用認證,配置鑑權

最佳實踐:

☑ 生產環境集羣部署(至少3節點)
☑ 使用MySQL持久化
☑ 啓用認證鑑權
☑ 命名空間環境隔離
☑ 配置定期備份
☑ 監控告警配置

參考資料

  1. Nacos官方文檔:https://nacos.io/docs/latest/
  2. Nacos GitHub:https://github.com/alibaba/nacos
  3. Spring Cloud Alibaba:https://sca.aliyun.com/docs/2023/

💡 建議:先在開發環境單機部署熟悉,生產環境務必集羣+MySQL持久化。