Nacos 注册与配置中心实战笔记

一、Nacos 是什么?

NacosNa ming and Co nfiguration S ervice)是阿里巴巴开源的动态服务发现、配置管理和服务管理平台,在 Spring Cloud Alibaba 体系中承担两大核心角色:

能力 作用
注册中心 服务注册(监控上下线)+ 服务发现(远程调用前找到目标地址)
配置中心 统一管理配置文件 + 推送配置变更

官网:Nacos 快速开始


二、安装与启动

  1. 下载 Nacos Server(建议 2.x 版本,如 2.4.3)
  2. 解压后进入 bin 目录
  3. 单机模式启动:
bash 复制代码
# Windows
startup.cmd -m standalone

# Linux / macOS
sh startup.sh -m standalone
  1. 访问控制台:http://localhost:8848/nacos
  2. 默认账号密码均为 nacos

三、注册中心

3.1 引入依赖

services 父模块或各微服务模块中引入:

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

3.2 服务注册

service-order(端口 8000)和 service-product(端口 9000)为例:

service-order --- application.properties

properties 复制代码
server.port=8000
spring.application.name=service-order
spring.cloud.nacos.server-addr=127.0.0.1:8848

service-product --- application.properties

properties 复制代码
server.port=9000
spring.application.name=service-product
spring.cloud.nacos.server-addr=127.0.0.1:8848

启动两个服务后,在 Nacos 控制台的「服务管理 → 服务列表」中即可看到注册成功的实例。

集群示例

  • service-order 启动 2 个实例:8000、8001
  • service-product 启动 3 个实例:9000、9001、9002

同一服务名下会显示多个实例,为后续负载均衡做准备。

3.3 服务发现

启动类添加 @EnableDiscoveryClient

java 复制代码
@EnableDiscoveryClient
@SpringBootApplication
public class ProductMainApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProductMainApplication.class, args);
    }
}

通过 DiscoveryClientNacosDiscoveryClient 获取所有服务及实例:

java 复制代码
@SpringBootTest
public class ProductApplicationTest {

    @Autowired
    DiscoveryClient discoveryClient;

    @Test
    public void discoveryClientTest() {
        for (String service : discoveryClient.getServices()) {
            System.out.println("service = " + service);
            for (ServiceInstance instance : discoveryClient.getInstances(service)) {
                System.out.println("host = " + instance.getHost());
                System.out.println("port = " + instance.getPort());
            }
        }
    }
}

四、远程调用

4.1 注册 RestTemplate

java 复制代码
@Configuration
public class OrderConfig {
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

4.2 手动发现 + 远程调用

java 复制代码
@Service
@Slf4j
public class OrderServiceImpl implements OrderService {

    @Autowired
    DiscoveryClient discoveryClient;
    @Autowired
    RestTemplate restTemplate;

    public Product getProductFromRemote(Long productId) {
        // 1. 从 Nacos 获取 service-product 的所有实例
        List<ServiceInstance> instances = discoveryClient.getInstances("service-product");
        ServiceInstance instance = instances.get(0);

        // 2. 拼接 URL 并发起远程请求
        String url = "http://" + instance.getHost() + ":" + instance.getPort()
                     + "/productId/" + productId;
        log.info("远程请求:{}", url);
        return restTemplate.getForObject(url, Product.class);
    }
}

测试:http://localhost:8000/create?userId=2&productId=23


五、负载均衡

引入 LoadBalancer 依赖:

xml 复制代码
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

方案一:LoadBalancerClient

java 复制代码
@Autowired
LoadBalancerClient loadBalancerClient;

public Product getProductFromRemoteWithLoadBalance(Long productId) {
    ServiceInstance choose = loadBalancerClient.choose("service-product");
    String url = "http://" + choose.getHost() + ":" + choose.getPort()
                 + "/productId/" + productId;
    return restTemplate.getForObject(url, Product.class);
}

方案二:@LoadBalanced 注解(推荐)

java 复制代码
@Configuration
public class OrderConfig {
    @LoadBalanced
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

远程调用时直接使用服务名代替 IP + 端口:

java 复制代码
public Product getProductFromRemoteWithLoadBalanceAnnotation(Long productId) {
    // service-product 会被 LoadBalancer 动态解析为某个实例
    String url = "http://service-product/productId/" + productId;
    return restTemplate.getForObject(url, Product.class);
}

多次请求会在多个实例间轮询分发。

思考:Nacos 宕机后,远程调用还能成功吗?

场景 结果
从未发起过远程调用,Nacos 宕机 ❌ 失败,拿不到服务地址
已成功调用过,Nacos 再宕机 ✅ 仍可调用(地址已缓存)
缓存中的目标实例宕机 ❌ 失败

原理

  1. 第一次远程调用:从 Nacos 拉取地址列表 → 选一个实例发请求
  2. 第二次及以后:直接使用本地缓存的地址列表,跳过 Nacos 查询

六、配置中心

6.1 引入依赖

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

6.2 客户端配置

service-order --- application.properties

properties 复制代码
server.port=8000
spring.application.name=service-order
spring.cloud.nacos.server-addr=127.0.0.1:8848
spring.config.import=nacos:service-order.properties
spring.cloud.nacos.config.import-check.enabled=false

import-check.enabled=false:暂未使用配置中心时可关闭检查,避免启动报错。

6.3 Nacos 控制台创建配置

在 Nacos 控制台「配置管理 → 配置列表」新建:

  • Data IDservice-order.properties
  • GroupDEFAULT_GROUP
  • 配置内容
properties 复制代码
order.timeout=30
order.auto-confirm=true

6.4 代码读取配置

java 复制代码
@RestController
public class OrderController {

    @Value("${order.timeout}")
    String orderTimeout;

    @Value("${order.auto-confirm}")
    String orderAutoConfirm;

    @GetMapping("/config")
    public String getConfig() {
        return orderTimeout + " : " + orderAutoConfirm;
    }
}

访问 http://localhost:8000/config 即可看到 Nacos 中的配置值。

6.5 配置优先级

Nacos 配置中心 > 本地 application.properties

若两边存在相同配置项,以 Nacos 为准。


七、配置动态刷新

修改 Nacos 配置后,不重启服务如何实时生效?

方案一:@RefreshScope + @Value

java 复制代码
@RefreshScope
@RestController
public class OrderController {
    @Value("${order.timeout}")
    String orderTimeout;
    // ...
}

方案二:@ConfigurationProperties(推荐,无感刷新)

java 复制代码
@Component
@ConfigurationProperties(prefix = "order")
@Data
public class OrderProperties {
    private String timeout;
    private String autoConfirm;
}
java 复制代码
@RestController
public class OrderController {

    @Autowired
    OrderProperties orderProperties;

    @GetMapping("/config")
    public String getConfig() {
        return orderProperties.getTimeout() + " : " + orderProperties.getAutoConfirm();
    }
}

使用 @ConfigurationProperties 绑定 Nacos 配置时,无需 @RefreshScope 即可自动刷新。

方案三:NacosConfigManager 监听变化

适合配置变更后执行业务逻辑(如发邮件通知):

java 复制代码
@SpringBootApplication
public class OrderMainApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderMainApplication.class, args);
    }

    @Bean
    ApplicationRunner applicationRunner(NacosConfigManager nacosConfigManager) {
        return args -> {
            ConfigService configService = nacosConfigManager.getConfigService();
            configService.addListener("service-order.properties", "DEFAULT_GROUP", new Listener() {
                @Override
                public Executor getExecutor() {
                    return Executors.newFixedThreadPool(4);
                }

                @Override
                public void receiveConfigInfo(String configInfo) {
                    System.out.println("配置已变更:" + configInfo);
                    // 可在此发送邮件、刷新缓存等
                }
            });
        };
    }
}

八、数据隔离(Namespace / Group)

Nacos 通过三层结构管理配置:

层级 用途 示例
Namespace 环境隔离 dev、test、prod
Group 服务/业务隔离 order、product
Data ID 具体配置文件 common.properties

application.yml 多环境示例

yaml 复制代码
server:
  port: 8000

spring:
  profiles:
    active: prod
  application:
    name: service-order
  cloud:
    nacos:
      server-addr: 127.0.0.1:8848
      config:
        import-check:
          enabled: false
        namespace: ${spring.profiles.active:public}

---
spring:
  config:
    import:
      - nacos:common.properties?group=order
      - nacos:database.properties?group=order
    activate:
      on-profile: dev

---
spring:
  config:
    import:
      - nacos:common.properties?group=order
      - nacos:database.properties?group=order
      - nacos:haha.properties?group=order
    activate:
      on-profile: test

---
spring:
  config:
    import:
      - nacos:common.properties?group=order
      - nacos:database.properties?group=order
      - nacos:hehe.properties?group=order
    activate:
      on-profile: prod

切换 spring.profiles.active 即可加载对应 Namespace 和配置文件组合。


九、快速上手清单

注册中心

  1. 引入 nacos-discovery 依赖
  2. 配置 spring.cloud.nacos.server-addr
  3. 启动 Nacos Server
  4. 启动微服务,在控制台确认注册
  5. 启动类加 @EnableDiscoveryClient
  6. 引入 loadbalancer,用 @LoadBalanced RestTemplate 实现负载均衡远程调用

配置中心

  1. 引入 nacos-config 依赖
  2. 配置 spring.config.import=nacos:xxx.properties
  3. 在 Nacos 控制台创建对应配置
  4. @Value + @RefreshScope@ConfigurationProperties 读取
  5. 多环境用 Namespace,多服务用 Group,多文件用不同 Data ID

十、小结

Nacos 是 Spring Cloud Alibaba 微服务体系的基础设施,核心价值在于:

  • 注册中心:让服务自动注册、自动发现,配合 LoadBalancer 实现负载均衡调用
  • 配置中心:集中管理配置、动态推送变更,支持 Namespace / Group 多维度隔离
  • 本地缓存:首次调用后缓存服务列表,Nacos 短暂宕机不影响已有调用链路

掌握 Nacos 的注册发现与配置管理能力,是后续学习 OpenFeign、Sentinel、Gateway 等组件的前提。

相关推荐
Csvn1 小时前
🐍 Day 6: Python 异常处理 — 防御式编程的核心
后端·python
叫我少年1 小时前
Git SSH 配置:从生成密钥到远程连接
git·后端
IT_陈寒1 小时前
Python多进程池的坑:子进程竟然不会退出
前端·人工智能·后端
叫我:松哥2 小时前
基于flask图书管理系统,技术栈flask+layui+sqlite+Echarts
后端·python·数据分析·flask·echarts·layui
铁皮饭盒2 小时前
网页端, 5.5mb谷歌模型, 识别躯干, 视频都不卡
前端·javascript·后端
WongKyunban2 小时前
Go语言的简洁并发编程
开发语言·后端·golang
mldong2 小时前
一条命令,十分钟:jeeflow 工作流应用的六语言一键部署
前端·后端·架构
Shawn_Shawn2 小时前
本体论的基本核心概念
后端·llm·领域驱动设计
凤山老林12 小时前
Spring Boot 3.x AOT 编译实战:从原理、踩坑到生产落地
java·spring boot·后端