Eureka、Nacos
版本说明:本文以 Spring Boot 3 / Spring Cloud 新版本思路为主。很多旧教程会使用 bootstrap.yml、Ribbon 等写法,学习时可以看,但自己写新项目时更建议优先使用 Spring Cloud LoadBalancer、spring.config.import 等新写法。
1. 微服务里的几个核心问题
单体项目里,前端请求通常直接打到一个后端服务:
浏览器/客户端
单体后端应用
数据库
微服务项目拆分后,系统可能变成这样:
浏览器/客户端
Gateway 网关
用户服务 user-service
订单服务 order-service
商品服务 product-service
用户库
订单库
商品库
拆分之后会出现几个新问题:
- 服务越来越多,调用方怎么知道某个服务现在在哪台机器、哪个端口?
- 同一个服务可能部署多个实例,请求应该打到哪一个实例?
- 服务上线、下线、宕机后,调用方如何及时感知?
- 公共认证、日志、限流、跨域等逻辑放在哪里更合适?
- 多个服务的配置如何统一管理、动态刷新?
对应到 Spring Cloud 生态中,常见组件分工如下:
| 问题 | 典型组件 | 作用 |
|---|---|---|
| 服务在哪里 | Eureka / Nacos Discovery | 服务注册与服务发现 |
| 多实例怎么选 | Spring Cloud LoadBalancer / Nacos 权重 | 客户端负载均衡 |
| 服务之间怎么调用 | OpenFeign | 声明式 HTTP 远程调用 |
| 外部请求从哪里进 | Spring Cloud Gateway | API 网关、统一入口 |
| 配置怎么统一管 | Nacos Config / Spring Cloud Config | 配置中心、动态配置 |

服务启动后注册到注册中心;调用方从注册中心发现目标服务实例;负载均衡器从多个实例中选一个;OpenFeign 发起服务间调用;Gateway 负责外部入口和公共过滤逻辑;Nacos 还可以统一管理配置。
2. Eureka:注册中心、服务注册与服务发现

2.1 Eureka 是什么
Eureka 是 Netflix OSS 体系里的服务注册与发现组件。它主要分成两类角色:
- Eureka Server:注册中心,负责保存服务实例信息。
- Eureka Client:微服务应用,启动后把自己注册到 Eureka Server,也可以从 Eureka Server 获取其他服务列表。
可以把 Eureka Server 理解成一个"服务通讯录"其他服务调用 user-service 时,不需要写死 IP 和端口,只需要通过服务名去查。
2.2 服务注册
服务注册指的是:服务启动后,把自己的服务名、IP、端口、健康状态等信息上报给注册中心。
以 user-service 为例,它启动时会把自己注册进去:
yaml
server:
port: 8081
spring:
application:
name: user-service
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
spring.application.name 很关键,它就是服务名。服务之间一般不是通过 localhost:8081 调用,而是通过 user-service 这个逻辑名称调用。
2.3 服务发现
服务发现指的是:调用方根据服务名,从注册中心拿到目标服务的实例列表。
例如 order-service 想调用 user-service,它不需要知道 user-service 部署在哪,只需要知道服务名:
text
order-service -> 注册中心 -> 查询 user-service -> 得到实例列表 -> 选择一个实例调用
如果 user-service 有多个实例:
text
user-service
├── 192.168.1.10:8081
├── 192.168.1.11:8081
└── 192.168.1.12:8081
注册中心会保存这些实例,调用方再结合负载均衡策略选择一个。
2.4 Eureka 简单部署流程
第一步:创建 Eureka Server
依赖示例:
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
启动类:
java
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
配置文件:
yaml
server:
port: 8761
spring:
application:
name: eureka-server
eureka:
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://localhost:8761/eureka/
这里的两个配置需要注意:
register-with-eureka: false:Eureka Server 不把自己当作普通服务注册。fetch-registry: false:Eureka Server 不需要从自己这里拉取服务列表。
启动后访问:
text
http://localhost:8761
可以看到 Eureka 控制台。
第二步:创建服务提供者 user-service
依赖示例:
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
配置文件:
yaml
server:
port: 8081
spring:
application:
name: user-service
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
简单接口:
java
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping("/{id}")
public String getUser(@PathVariable Long id) {
return "user id = " + id;
}
}
启动后,Eureka 控制台中会出现 USER-SERVICE。
第三步:创建服务消费者 order-service
yaml
server:
port: 8082
spring:
application:
name: order-service
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
后面可以通过 OpenFeign 或 RestTemplate 调用 user-service。
3. 负载均衡:为什么不能只调用一个实例

3.1 负载均衡解决什么问题
当一个服务部署多个实例时,请求不能永远打到同一个实例,否则会导致:
- 某台机器压力过大;
- 其他实例空闲浪费;
- 单个实例宕机后请求失败;
- 系统整体吞吐量上不去。
负载均衡就是在多个实例中选择一个实例来处理请求。
3.2 服务名调用与负载均衡
以前很多教程会讲 Ribbon,现在新版本更推荐 Spring Cloud LoadBalancer。
服务调用时通常不是这样写:
text
http://localhost:8081/users/1
而是这样写:
text
http://user-service/users/1
这里的 user-service 不是域名,而是注册中心中的服务名。调用流程大致是:
- 先根据
user-service去注册中心拉取实例列表; - 负载均衡器从列表里选一个实例;
- 把
http://user-service/users/1转成类似http://192.168.1.10:8081/users/1; - 最后发起真正的 HTTP 请求。
3.3 常见负载均衡策略
常见策略包括:
- 轮询:第 1 次打实例 A,第 2 次打实例 B,第 3 次打实例 C,然后循环。
- 随机:随机选择一个实例。
- 权重:权重越高,被选中的概率越大。
- 同集群优先:消费者优先调用同一个集群或同一个机房内的服务实例。
4. Nacos:注册中心 + 配置中心

4.1 Nacos 是什么
Nacos 是阿里开源的动态服务发现、配置管理和服务管理平台。在 Spring Cloud Alibaba 体系中,Nacos 通常承担两个角色:
- Nacos Discovery:服务注册与发现,类似 Eureka。
- Nacos Config:配置中心,集中管理应用配置,支持动态刷新。
所以 Nacos 比 Eureka 的能力更综合。Eureka 主要关注服务注册发现,而 Nacos 同时可以做注册中心和配置中心。
4.2 Nacos 服务注册与发现
服务启动后,将自己注册到 Nacos:
yaml
server:
port: 8081
spring:
application:
name: user-service
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
启动多个服务后,可以在 Nacos 控制台看到服务列表。
Nacos 控制台默认地址通常是:
text
http://localhost:8848/nacos
常见默认账号密码是:
text
nacos / nacos
具体以你本地安装版本为准。
4.3 服务下线
服务下线有两种理解:
一种是应用真正停止 。例如你关闭了某个 user-service 实例。注册中心会通过心跳或健康检查发现它不可用,然后把它从可用列表中剔除或标记异常。
另一种是手动下线实例。在 Nacos 控制台中可以把某个实例临时下线。这样它虽然进程还在,但消费者不会再优先调用它。
典型使用场景:
- 服务要灰度发布,先下线旧实例;
- 某台机器异常,先摘掉流量;
- 临时维护,不希望继续接收请求。
理解重点:
下线不是删除服务,而是让该实例暂时不参与调用。
4.4 权重配置
Nacos 支持给实例设置权重。权重越高,被调用的概率越大。
例如:
text
user-service 实例 A:权重 1
user-service 实例 B:权重 5
如果负载均衡策略使用权重,实例 B 大约会获得更多流量。
配置示例:
yaml
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
weight: 5
权重常用于:
- 新版本灰度发布:新版本先给较小权重,观察稳定后再逐步提高;
- 机器性能不同:高配置机器设置更高权重;
- 临时降流量:把某个实例权重调低。
少量流量
更多流量
consumer
Nacos + LoadBalancer
user-service v1 / weight=1
user-service v2 / weight=5
4.5 同集群优先
同集群优先的意思是:消费者优先调用与自己处在同一集群、同一机房或同一区域的服务实例。
例如:
text
上海集群:user-service A、order-service A
北京集群:user-service B、order-service B
上海的 order-service 优先调用上海的 user-service,北京的 order-service 优先调用北京的 user-service。
这个做的好处是网络延迟更低、跨机房调用更少,速度更加快。还有就是一个集群故障时,可以再考虑降级调用其他集群。
配置示例:
yaml
spring:
cloud:
nacos:
discovery:
cluster-name: SHANGHAI
如果要让 Spring Cloud LoadBalancer 更好地结合 Nacos 的集群信息,需要根据项目版本启用对应的 Nacos LoadBalancer 集成配置,例如:
yaml
spring:
cloud:
loadbalancer:
nacos:
enabled: true
权重解决"谁多接一点流量",集群优先解决"尽量调用离我近的服务"。
4.6 环境隔离:Namespace、Group、DataId
Nacos 里常见的隔离概念有三个:
| 概念 | 用途 | 类比 |
|---|---|---|
| Namespace | 环境级隔离 | dev、test、prod 三个空间 |
| Group | 分组隔离 | 同一环境下按业务线或项目分组 |
| DataId | 配置文件标识 | user-service-dev.yml |
最常用的是 Namespace。比如你可以创建三个命名空间:
text
dev 开发环境
test 测试环境
prod 生产环境
这样开发环境的服务和配置不会误连到生产环境。
示例:
yaml
spring:
cloud:
nacos:
discovery:
namespace: dev-namespace-id
config:
namespace: dev-namespace-id
注意:namespace 配的通常不是命名空间名称,而是命名空间 ID。
4.7 Nacos 配置中心
配置中心的价值是:把配置从代码包里抽出来,集中放到 Nacos 管理。
以前配置可能写在每个服务自己的 application.yml 中:
用了 Nacos Config 后,可以把这些配置放在 Nacos 控制台中。应用启动时从 Nacos 拉取配置,运行中还可以监听配置变化。
Nacos Config user-service Nacos Config user-service 启动时拉取 user-service-dev.yml 返回配置内容 使用配置启动 配置变化通知 动态刷新部分配置
现代写法示例:
yaml
spring:
application:
name: user-service
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
group: DEFAULT_GROUP
file-extension: yaml
config:
import:
- optional:nacos:user-service-dev.yaml
如果使用动态刷新,可以配合 @RefreshScope,这就支持不用重新启动服务即可更改配置:
java
@RestController
@RefreshScope
public class ConfigController {
@Value("${user.level:normal}")
private String userLevel;
@GetMapping("/config/user-level")
public String getUserLevel() {
return userLevel;
}
}
在 Nacos 控制台修改配置后,接口返回值可以随配置变化而变化。
4.8 Nacos 简单部署流程
第一步:启动 Nacos Server
学习环境可以直接本地启动 Nacos 单机版,常见端口是8848
启动成功后访问:
text
http://localhost:8848/nacos
第二步:服务接入 Nacos Discovery
添加依赖:
xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
配置:
yaml
server:
port: 8081
spring:
application:
name: user-service
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
启动后在控制台查看服务列表。
第三步:服务接入 Nacos Config
添加依赖:
xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
配置:
yaml
spring:
application:
name: user-service
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
file-extension: yaml
config:
import:
- optional:nacos:user-service-dev.yaml
然后在 Nacos 控制台新建配置:
text
Data ID: user-service-dev.yaml
Group: DEFAULT_GROUP
配置格式: YAML
配置内容示例:
yaml
user:
level: vip
第四步:多环境隔离
创建命名空间:
text
dev
prod
然后在服务配置中指定命名空间 ID:
yaml
spring:
cloud:
nacos:
discovery:
namespace: dev-namespace-id
config:
namespace: dev-namespace-id
这样开发环境服务只注册到开发环境空间,开发环境配置也只从开发空间读取。
5. Eureka 与 Nacos 的区别

| 对比项 | Eureka | Nacos |
|---|---|---|
| 定位 | 服务注册与发现 | 服务注册发现 + 配置中心 + 服务管理 |
| 生态 | Netflix OSS / Spring Cloud Netflix | Spring Cloud Alibaba / Nacos 生态 |
| 配置中心 | 不提供,需要搭配其他组件 | 原生支持配置中心 |
| 控制台能力 | 相对简单,主要查看服务实例 | 更丰富,可管理服务、实例、权重、配置、命名空间等 |
| 权重配置 | 原生能力弱,通常依赖负载均衡策略扩展 | 原生支持实例权重 |
| 环境隔离 | 通常靠不同注册中心或配置区分 | 支持 Namespace、Group 等隔离方式 |
| 服务下线 | 更多依赖心跳和实例状态 | 控制台可更方便地下线实例、调整权重 |
| 适合场景 | 学习注册中心原理、传统 Spring Cloud 项目 | 国内项目常见,适合注册中心和配置中心统一管理 |
希望对你有所帮助~~