5 个注解让服务发现和配置中心同时就位:Spring Cloud Alibaba 集成 Nacos 的完整模板
5 个注解让服务发现和配置中心同时就位:Spring Cloud Alibaba 集成 Nacos 的完整模板
一个 pom.xml 和两个 yml,省掉 Eureka + Apollo 两套部署
2022 年公司技术栈改造。当时线上跑着 Eureka 做注册中心,Apollo 做配置中心。两套系统,两拨维护人员,两个端口号要记住,两个健康检查要配,两个告警规则要写。
迁移到 Nacos 之后,Eureka 那三台机器回收了。Apollo 那两台也回收了。所有配置文件从 Apollo 的 Portal 搬到 Nacos 控制台,所有服务注册从 eureka.client.serviceUrl.defaultZone 切到 spring.cloud.nacos.discovery.server-addr。
整个过程里,Spring Cloud Alibaba 的 starter 做了 90% 的工作。你只需要加依赖、配地址、加注解。这篇文章给一套可复制的集成模板——从空项目到服务注册成功、配置动态刷新可用的完整步骤。
全景:5 个注解各管什么
5 个注解的分工:@SpringBootApplication 启动、@EnableDiscoveryClient 注册、@RestController 暴露接口、@RefreshScope 刷新、@Value/@NacosValue 注入配置。
🔗 配置刷新背后的长轮询和 gRPC Push 是怎么回事?看这篇:配置推送延迟从 30 秒打到 10 毫秒
第一步:依赖——两个 starter 就够了
<!-- pom.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>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- 服务注册与发现 -->
<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>
<!-- Spring Boot Web(让服务有一个可探测的 HTTP 端口) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
两个 starter,一个 web。没有 Eureka client,没有 Apollo client。
版本关系要留意:Spring Cloud Alibaba 2023.0.1.0 → Spring Boot 3.2.x → Nacos 2.3.x。跨大版本会有兼容问题。不匹配的话,registerInstance 调成功但 Nacos 控制台看不到——protobuf 版本冲突是根因。
第二步:配置——bootstrap.yml 和 application.yml 的分工
Spring Cloud 的配置加载顺序是 bootstrap.yml → 从 Nacos 拉配置 → application.yml。所以连 Nacos 的地址要写在 bootstrap.yml 里,application.yml 的本机配置可以被 Nacos 覆盖。
# bootstrap.yml —— 引导配置,最先加载
spring:
application:
name: order-service # 服务名 = Nacos 里的 serviceName
cloud:
nacos:
discovery:
server-addr: 10.0.1.10:8848 # Nacos 地址
namespace: prod # 命名空间(隔离环境用)
group: DEFAULT_GROUP
ephemeral: true # 临时实例(默认 true,走 Distro)
config:
server-addr: 10.0.1.10:8848 # 配置中心地址(可以和注册中心用同一个)
namespace: prod
group: DEFAULT_GROUP
file-extension: yaml # 配置文件的格式
shared-configs: # 共享配置(多服务共用的那类配置)
- data-id: common.yaml
group: DEFAULT_GROUP
refresh: true # 共享配置也要支持动态刷新
# application.yml —— 应用配置,可被 Nacos 配置覆盖
server:
port: 8080
logging:
level:
com.alibaba.nacos: warn # Nacos 客户端日志别太多
关键点:
spring.application.name就是 Nacos 里的 serviceName——必须和 Nacos 控制台注册的 serviceName 一致。namespace不填默认走public命名空间——生产环境不要用 public,用独立的命名空间隔离。shared-configs是容易被忽略的一个功能——多个微服务共用的配置(比如数据库连接池参数),放这里,不用每个服务单独维护一份。
第三步:启动类——一个注解完成注册
package com.example.order;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient // 就这一个。服务启动后自动注册到 Nacos。
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
@EnableDiscoveryClient 触发 Spring Cloud 的服务注册流程。底层调用 NacosAutoServiceRegistration.start() → NacosNamingService.registerInstance()。你在第五篇 5.2 见过这条链路。
第四步:配置动态刷新——@RefreshScope + @Value
package com.example.order.controller;
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 OrderController {
@Value("${order.timeout:3000}")
private int timeout;
@Value("${order.discount:0.95}")
private double discount;
@GetMapping("/order/config")
public String getConfig() {
return "timeout=" + timeout + ", discount=" + discount;
}
}
原理不复杂:Nacos 配置变更后,Spring Cloud Alibaba 发一个 RefreshEvent。Spring Cloud Context 收到事件,找到所有加了 @RefreshScope 的 Bean,销毁旧的,下次访问时创建新的。新 Bean 重新执行 @Value 注入,拿到新配置。
@NacosValue vs @Value:Spring Cloud Alibaba 提供了 @NacosValue,比 @Value 多了 autoRefreshed 参数:
@NacosValue(value = "${order.timeout:3000}", autoRefreshed = true)
private int timeout;
如果用的是 Spring Cloud 原生 @Value,需要 @RefreshScope 配合。如果用 @NacosValue(autoRefreshed = true),不需要 @RefreshScope 也能刷新。但团队里混用两者会让人困惑——建议统一用 @RefreshScope + @Value,概念清晰。
第五步:验证——四步检查
# 1. 启动后检查注册
curl http://10.0.1.10:8848/nacos/v1/ns/instance/list?serviceName=order-service
# 返回 JSON,能看到你的 IP 和端口
# 2. 检查配置拉取
curl http://10.0.1.10:8848/nacos/v1/cs/configs?dataId=order-service.yaml&group=DEFAULT_GROUP
# 返回你在 Nacos 控制台填的配置内容
# 3. 改配置验证刷新
# 在 Nacos 控制台把 order.timeout 从 3000 改为 5000,点发布
curl http://localhost:8080/order/config
# 应该立即显示 timeout=5000
# 4. 查看 Nacos 控制台
# → 服务列表 → 找到 order-service → 实例列表 → 看到你的实例,状态"健康"
一张图带走:集成路径决策树
截图保存。以后新项目集成 Nacos,从 Spring Cloud 版本号开始走这张图。版本→依赖→注解→检查点,四步走完。
你们团队是 Nacos 全家桶还是混着用?评论区留个数字:1=注册+配置全用Nacos 2=Nacos注册+Apollo配置 3=Eureka注册+Nacos配置 4=还在用Eureka+Apollo。顺便说一句,迁移遇到过最坑的兼容问题是啥。
更多推荐




所有评论(0)