Skip to content

Nacos 教程


一、基础理论

1. 定位

  • 注册中心:服务注册、服务发现、健康检查、负载均衡。
  • 配置中心:集中化管理配置,支持动态刷新。

2. 核心架构

  • Server:提供 OpenAPI,分 Naming(注册)和 Config(配置)模块。
  • Client:嵌入式 SDK,与 Server 保持连接获取服务列表和配置。
  • 2.x 核心变化:使用 gRPC 长连接 替代 1.x 的 HTTP 短连接 + 定时心跳。

3. 注册中心原理

  1. 服务启动通过 HTTP/gRPC 向 Nacos Server 注册实例。
  2. 1.x:Client 每 5s 发 HTTP 心跳;Server 15s 标记不健康,30s 剔除。
  3. 2.x:基于 gRPC 长连接的心跳检测,连接断开即感知。
  4. 消费者通过 本地缓存 + 订阅推送 方式获取实例列表,避免单点压力。

本地缓存 + 订阅推送拆解

  • 消费者启动时从 Nacos Server 拉取全量提供者列表,缓存到 本地 JVM 内存(并落盘快照)。
  • 每次调用直接从本地内存取 IP:Port,不经过 Server,调用速度纳秒级。
  • 当提供者上下线时,Server 主动推送变更给消费者,消费者更新本地缓存。
  • 好处:避免所有调用都查 Server 导致其成为流量瓶颈;Server 挂了也能靠本地缓存继续调用一段时间。

4. 配置中心原理

  • Client 启动时拉取全量配置并缓存到本地快照。
  • 通过 HTTP 长轮询(Long Polling) 监听变更:请求挂起 29.5s,期间配置变更立即返回;无变更则超时后重新发起。
  • 变更后 Client 发布 RefreshEvent,配合 @RefreshScope 刷新上下文。

5. 一致性协议

  • 注册中心:默认 AP(Distro 协议,阿里自研),优先保证可用性;支持切换 CP(Raft)。
  • 配置中心:默认 CP(使用 JRaft 保证配置一致性)。

6. 经典对比

维度EurekaConsulNacos
CAPAPCPAP/CP 切换
协议HTTPHTTP/DNSHTTP/gRPC
健康检查Client 心跳TCP/HTTP/GRPCClient 心跳/服务端探测
多语言Java 友好全语言Java/Go/Python 等
SpringCloud原生支持集成需依赖Alibaba 官方支持

二、工作实践(复制即用)

1. 单机安装

bash
# 下载解压后启动
sh startup.sh -m standalone

# 控制台
http://localhost:8848/nacos
# 账号/密码:nacos/nacos

# ⚠️ 2.x 必须暴露端口:8848(HTTP) + 9848(gRPC)
bash
docker run --name nacos \
  -e MODE=standalone \
  -p 8848:8848 \
  -p 9848:9848 \
  -d nacos/nacos-server:v2.3.0

2. 服务注册中心(Provider)

pom.xml

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

application.yml

yaml
server:
  port: 8081

spring:
  application:
    name: order-service
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        namespace: public
        group: DEFAULT_GROUP

启动类

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

3. 服务消费与调用(Consumer + OpenFeign)

pom.xml

xml
<!-- 注册发现 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

<!-- 声明式调用 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

<!-- 负载均衡器(Spring Cloud 2020+ 替代 Ribbon) -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

Feign 接口

java
@FeignClient(name = "order-service")
public interface OrderClient {

    @GetMapping("/order/{id}")
    String getOrder(@PathVariable("id") Long id);
}

调用方代码

java
@RestController
public class UserController {

    @Autowired
    private OrderClient orderClient;

    @GetMapping("/user/order/{id}")
    public String getOrder(@PathVariable Long id) {
        return orderClient.getOrder(id);
    }
}

调用方启动类

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

4. 配置中心

pom.xml

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

application.yml(Spring Cloud Alibaba 2021+ 推荐写法)

yaml
server:
  port: 8081

spring:
  application:
    name: order-service
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
        file-extension: yaml
  config:
    import:
      - nacos:order-service.yaml?group=DEFAULT_GROUP&refreshEnabled=true

Nacos 控制台新建配置

字段
Data IDorder-service.yaml
GroupDEFAULT_GROUP
配置格式YAML
配置内容my:
  name: nacos-config

代码读取(支持热更新)

java
@RestController
@RefreshScope
public class ConfigController {

    @Value("${my.name:default}")
    private String name;

    @GetMapping("/name")
    public String name() {
        return name;
    }
}

三、核心速查表

配置项说明
server-addrNacos 地址,集群用逗号分隔
namespace命名空间 ID,用于环境隔离
group配置/服务分组,默认 DEFAULT_GROUP
file-extension配置格式:yaml / properties
spring.config.import导入 Nacos 配置的入口(2.7+ 必须显式声明)
@RefreshScope作用在 Bean 上,实现配置热刷新
9848Nacos 2.x 必须暴露的 gRPC 端口

四、排错速查

现象解决
服务注册不上检查 9848 端口是否开放;检查 server-addr 是否正确
Feign 调用 503 / no available server1. 确认提供者已注册
2. 消费者是否引入 spring-cloud-starter-loadbalancer
配置不刷新检查 @RefreshScope;检查 spring.config.import 是否加了 refreshEnabled=true