🔍 微服务注册中心的核心挑战
想象一下,当我们的服务提供者(如 user-service)部署了多个实例时(如下图),会面临几个关键问题:

- 服务发现 :服务消费者(如
order-service)如何动态感知user-service实例的 IP 和端口? - 负载均衡 :面对多个
user-service实例,order-service如何智能选择调用目标? - 健康监测 :
order-service如何实时判断某个user-service实例是否存活?
🛠 解决方案:注册中心
这些问题正是 注册中心(Registry) 的核心作用!Spring Cloud 生态中,Eureka 和 Nacos 是两大主流选择。
📡 Eureka 的工作原理

- 服务注册 :
user-service启动时,向 Eureka Server 注册自身信息(服务名、IP、端口等)。 - 服务发现 :
order-service根据服务名(如userservice)从 Eureka Server 拉取可用的实例列表。 - 负载均衡 :
order-service使用算法(如轮询)从列表中选择一个实例发起调用。 - 健康检查 :
user-service定期(默认 30 秒)发送心跳 给 Eureka Server。若长时间无心跳,Eureka Server 会将其从列表剔除。
💡 提示:一个微服务可同时是提供者和消费者,注册/发现逻辑统一封装在
eureka-client组件中。
🚀 快速搭建 Eureka Server
- 创建独立服务模块 (
eureka-server)
在cloud-demo父工程下,创建一个子模块: 
-
添加依赖 (
pom.xml):引入SpringCloud为eureka提供的starter依赖:
xml<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> -
编写启动类 (添加
@EnableEurekaServer)给eureka-server服务编写一个启动类,一定要添加一个 @EnableEurekaServer注解,开启eureka的注册中心功能:
less@SpringBootApplication @EnableEurekaServer public class EurekaApplication { public static void main(String[] args) { SpringApplication.run(EurekaApplication.class, args); } }

-
配置文件 (
application.yml):编写一个application.yml文件,内容如下:
yamlserver: port: 10086 spring: application: name: eurekaserver eureka: client: service-url: defaultZone: http://localhost:10086/eureka # 单机指向自己 -
启动并访问 :
http://localhost:10086

📝 服务注册与发现实践
-
服务注册 (user-service):
- 添加依赖 (
eureka-client客户端依赖)
在user-service的pom文件中,引入下面的eureka-client依赖:
xml<!--eureka客户端依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>-
配置:
在user-service中,修改application.yml文件,添加服务名称、eureka地址:
yamlspring: application: name: userservice # 服务名 eureka: client: service-url: defaultZone: http://localhost:10086/eureka # Eureka地址 -
启动多个实例(不同端口)后,即可在 Eureka 控制台看到注册信息。
为了演示一个服务有多个实例的场景,我们添加一个SpringBoot的启动配置,再启动一个user-service。
首先,复制原来的user-service启动配置:
- 添加依赖 (

然后,在弹出的窗口中,填写信息:
启动两个user-service实例:

查看eureka-server管理页面:

- 服务发现与调用 (order-service):
下面,我们将order-service的逻辑修改:向eureka-server拉取user-service的信息,实现服务发现。
- 添加依赖 (
eureka-client客户端依赖)
服务发现、服务注册统一都封装在eureka-client依赖,因此这一步与服务注册时一致。
在order-service的pom文件中,引入下面的eureka-client依赖:
xml
<!--eureka客户端依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
- 配置 (同上,服务名改为
orderservice)
在order-service中,修改application.yml文件,添加服务名称、eureka地址:
yaml
spring:
application:
name: orderservice #Order服务的服务名称
eureka:
client:
service-url:
defaultZone: http://localhost:10086/eureka # Eureka地址
- 服务拉取和负载均衡:
我们要去eureka-server中拉取user-service服务的实例列表,并且实现负载均衡。
不过这些动作不用我们去做,只需要添加一些注解即可, 在order-service的OrderApplication中,给RestTemplate这个Bean添加一个
- 给
RestTemplateBean 添加@LoadBalanced注解。

- 使用服务名 发起调用:
http://userservice/user/1(Spring Cloud 自动处理地址转换)。
修改order-service服务中的order.service包下的OrderService类中的queryOrderById方法。修改访问的url路径,用服务名代替ip、端口:

⚖️ Ribbon:负载均衡引擎
@LoadBalanced 背后的功臣是 Ribbon的组件,来实现负载均衡功能的。
🔬 Ribbon 工作原理

- 拦截请求 :
LoadBalancerInterceptor拦截RestTemplate发出的请求 (http://userservice/user/1)。 - 提取服务名 :获取 URL 中的主机名 (
userservice)。 - 拉取服务列表 :向注册中心 (Eureka) 请求
userservice的可用实例列表。 - 负载均衡 :使用
IRule算法 (默认RoundRobinRule轮询) 选择一个实例 (localhost:8081)。 - 重构请求 :将原 URL 中的服务名替换为选中的实例地址 (
http://localhost:8081/user/1)。 - 发起真实调用。

🎯 负载均衡策略 (IRule)
负载均衡的规则都定义在IRule接口中,而IRule有很多不同的实现类:
不同规则的含义如下:
| 策略类 | 规则描述 |
|---|---|
RoundRobinRule |
默认策略。简单轮询服务列表。 |
RandomRule |
随机选择一个可用实例。 |
ZoneAvoidanceRule |
推荐。优先选择同区域 (Zone) 的实例,区域内再做轮询。优化延迟和故障。 |
AvailabilityFilteringRule |
忽略多次连接失败或并发过高的服务器。 |
WeightedResponseTimeRule |
根据实例响应时间分配权重,响应越快权重越高。 |
BestAvailableRule |
选择并发请求数最低的实例。 |
RetryRule |
带有重试机制的轮询。 |
自定义策略 (以 RandomRule 为例):
-
代码方式:
在order-service中的OrderApplication类中,定义一个新的IRule:
typescript@Bean public IRule randomRule() { return new RandomRule(); // 随机策略 } -
配置文件方式 (
order-service的application.yml):添加新的配置也可以修改规则
yamluserservice: # 指定对哪个服务生效 ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
⚡ 性能优化:饥饿加载 (Eager Loading)
Ribbon 默认懒加载 ,即第一次访问时才会去创建LoadBalanceClient首次请求耗时较长。开启饥饿加载可在应用启动时初始化负载均衡客户端:
通过下面配置开启饥饿加载yaml
yaml
ribbon:
eager-load:
enabled: true # 开启饥饿加载
clients: userservice # 指定对哪些服务进行饥饿加载 (可多个)
🚀 Nacos:更强大的注册中心
Nacos 是阿里巴巴的产品,现在是SpringCloud中的一个组件。相比Eureka功能更加丰富,在国内受欢迎程度较高。
🛠 Nacos 安装与启动
-
下载 Nacos Server。
-
启动 (单机模式):进入
bin目录执行:bash
bashstartup.cmd -m standalone # Windows sh startup.sh -m standalone # Linux/macOS -
访问控制台 :
http://localhost:8848/nacos(默认账号/密码:nacos)。
🔧 服务注册到 Nacos
Nacos是SpringCloudAlibaba的组件,而SpringCloudAlibaba也遵循SpringCloud中定义的服务注册、服务发现规范。因此使用Nacos和使用Eureka对于微服务来说,并没有太大区别。
主要差异在于:
- 依赖不同
- 服务地址不同
-
添加依赖 :
在cloud-demo父工程的pom文件中的
<dependencyManagement>中引入SpringCloudAlibaba的依赖:xml<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.2.6.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency>然后在user-service和order-service中的pom文件中引入nacos-discovery依赖:
xml<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>⚠️ 记得移除或注释掉
eureka-client依赖。 -
配置地址 (
application.yml):在user-service和order-service的application.yml中添加nacos地址:
yamlspring: cloud: nacos: server-addr: localhost:8848 # Nacos Server 地址⚠️ 记得移除或注释掉
eureka的地址。 -
重启服务,在 Nacos 控制台 服务管理 > 服务列表 中查看注册信息。

🌐 Nacos 高级特性
一个服务 可以有多个实例,例如我们的user-service,可以有:
- 127.0.0.1:8081
- 127.0.0.1:8082
- 127.0.0.1:8083
假如这些实例分布于全国各地的不同机房,例如:
- 127.0.0.1:8081,在上海机房
- 127.0.0.1:8082,在上海机房
- 127.0.0.1:8083,在杭州机房
Nacos就将同一机房内的实例 划分为一个集群。
也就是说,user-service是服务,一个服务可以包含多个集群,如杭州、上海,每个集群下可以有多个实例,形成分级模型,如图:
微服务互相访问时,应该尽可能访问同集群实例,因为本地访问速度更快。当本集群内不可用时,才访问其它集群。例如:
杭州机房内的order-service应该优先访问同机房的user-service。
-
服务分级模型 (集群):
-
概念 :将同一机房/地域的实例划分到一个集群 (Cluster)。
-
优势 :优先访问同集群实例,降低延迟;跨集群访问作为容灾后备。
-
配置 (实例的
application.yml):修改user-service的application.yml文件,添加集群配置:
yamlspring: cloud: nacos: discovery: cluster-name: SZ # 集群名称 (如 SZ-深圳, HZ-杭州)重启两个user-service实例后,我们可以在nacos控制台看到下面结果:
-

-
同集群优先负载均衡:
默认的
ZoneAvoidanceRule并不能实现根据同集群优先来实现负载均衡。因此Nacos中提供了一个
NacosRule的实现,可以优先从同集群中挑选实例。-
配置
order-service的集群 (同上)。 -
修改负载均衡规则为 NacosRule (
order-service的application.yml):修改负载均衡规则:
yamluserservice: # 服务提供者名称 ribbon: NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # Nacos集群优先策略
-
-
权重配置:
但默认情况下NacosRule是同集群内随机挑选,不会考虑机器的性能问题,因此,Nacos提供了权重配置来控制访问频率,权重越大则访问频率越高。
- 场景:根据机器性能分配流量。
- 操作 :在 Nacos 控制台 > 服务详情 > 实例列表 > 编辑实例,修改权重 (0-1, 权重越大访问频率越高)。权重为 0 则完全不被访问。
4. 环境隔离 (Namespace):
Nacos提供了namespace来实现环境隔离功能,nacos中可以有多个namespace,namespace下可以有group、service等
-
场景:隔离开发、测试、生产等环境。
-
操作:
-
Nacos 控制台 > 命名空间 > 创建命名空间 (
dev,test,prod),获取生成的 Namespace ID。 -
微服务配置:
修改order-service的application.yml文件:
yamlspring: cloud: nacos: discovery: namespace: 492a7d5d-237b-46a1-a99a-fa8e98e4b0f9 # 填入目标Namespace ID
-
-
效果 :不同 Namespace 的服务相互不可见。


⚖️ Nacos vs Eureka 核心区别
| 特性 | Nacos | Eureka |
|---|---|---|
| 实例类型 | 临时实例 (默认):心跳异常自动剔除。 非临时实例 (ephemeral: false):不自动剔除,需主动下线。 |
所有实例均为临时实例,心跳异常自动剔除。 |
| 健康检查 | 主动探测 (对非临时实例) + 心跳。 | 仅心跳。 |
| 服务列表更新 | 推送模式 (变更实时性强)。 | 定时拉取 (有延迟)。 |
| CAP 模型 | 临时实例:AP 。 存在非临时实例:CP。 | AP。 |
| 额外功能 | 配置中心 、权重 、集群 、命名空间。 | 核心注册与发现。 |
配置非临时实例 (Nacos):
yaml
spring:
cloud:
nacos:
discovery:
ephemeral: false # 设置为非临时实例
总结:
Nacos和Eureka整体结构类似,服务注册、服务拉取、心跳等待,但是也存在一些差异

- Eureka:Spring Cloud Netflix 原生方案,简单可靠,AP 模型保证高可用。
- Nacos:功能强大 (注册中心 + 配置中心),支持集群、权重、环境隔离,健康检查更灵活 (支持主动探测和临时/非临时实例),国内生态活跃。
根据项目需求和团队技术栈选择合适的注册中心!💪🏻