Netflix Eureka:微服务如何找到彼此?

举报
yd_236998400 发表于 2026/11/02 09:57:41 2026/11/02
【摘要】 Netflix Eureka:微服务如何找到彼此?摘要: 微服务实例会动态扩缩容、重启和迁移,靠写死 IP 地址很快就会把系统变成一张过期的通讯录。Netflix Eureka 提供了一套服务注册与发现机制:实例登记自己的位置,客户端查询注册表,再结合本地缓存与客户端负载均衡完成服务调用。关键词: Netflix Eureka、服务注册、服务发现、Spring Cloud、微服务 一、从“...

Netflix Eureka:微服务如何找到彼此?

摘要: 微服务实例会动态扩缩容、重启和迁移,靠写死 IP 地址很快就会把系统变成一张过期的通讯录。Netflix Eureka 提供了一套服务注册与发现机制:实例登记自己的位置,客户端查询注册表,再结合本地缓存与客户端负载均衡完成服务调用。

关键词: Netflix Eureka、服务注册、服务发现、Spring Cloud、微服务

一、从“写死地址”说起

假设订单服务要调用库存服务。最直接的写法,是把库存服务地址写进配置:http://10.0.2.17:8080。

开发环境里这招挺省事,规模一大就开始闹脾气:库存服务一扩容,调用方不知道新实例;实例换机器或端口,配置得跟着改;某台机器挂了,旧地址还留在通讯录里。服务之间原本只是互相调用,最后却变成了“全公司一起维护 IP 地址表”。

服务注册与发现就是来解决这件事的。服务实例启动后向注册中心登记自己的身份和访问地址;调用方按服务名查询可用实例,再把请求发给其中一个。Netflix Eureka 是 Netflix 开源的 RESTful 服务注册与发现组件,主要面向中间层服务的发现、负载均衡与故障转移。citeturn175258search0

二、Eureka 的核心角色

Eureka 通常由两类角色组成:

  • Eureka Server: 维护服务实例注册信息,并向客户端提供注册表查询接口。多个 Server 可以互相作为 peer 同步注册信息。
  • Eureka Client: 既可以是向 Server 登记自身信息的服务实例,也可以是查询其他服务地址的调用方。一个应用往往同时承担这两种角色。

注册信息通常包含应用名、实例 ID、主机名、端口、状态和元数据等。Spring Cloud Netflix 会把 Spring Boot 应用接入 Eureka;引入 Eureka Client starter 后,应用可以自动注册,同时作为客户端发现其他服务。citeturn714340view3turn714340view3

可以把它想成一个会定期更新的通讯录:服务实例负责报到,Eureka 负责维护目录,调用方根据服务名查到当前可用的地址。

三、一次注册与调用是怎么完成的

典型流程大致如下:

  1. 实例启动并注册。 服务启动后,Eureka Client 将应用名、实例地址、端口及元数据发送给 Eureka Server。
  2. 持续发送心跳。 客户端周期性续约,表明实例仍在运行。若实例正常关闭,客户端会尝试注销;若异常失联,Server 会在后续过期清理中处理。
  3. 客户端拉取注册表。 调用方从 Eureka 获取可用实例列表,并在本地缓存注册信息。
  4. 按服务名选择实例。 应用使用 Spring Cloud LoadBalancer 等客户端侧组件,从列表中选择目标实例,再发起 HTTP/RPC 请求。
  5. 状态变化传播。 注册、续约、注销等变更会在 Eureka 集群节点间复制;客户端通过后续注册表更新看到变化。

一个关键点:Eureka 负责服务目录,不负责替你的业务请求做完整的负载均衡。 它给客户端提供实例信息;具体选择哪个实例,通常由调用端的负载均衡组件完成。Spring Cloud Netflix 也提供 Eureka 与 Spring Cloud LoadBalancer 的集成。citeturn714340view3

四、为什么 Eureka Client 也要缓存注册表

如果每次业务调用前都同步询问注册中心,Eureka Server 就会落在每条业务链路的热路径上:注册中心一抖,服务调用也跟着抖。Eureka 客户端维护本地注册表缓存,服务发现通常先从本地信息中完成,降低了对中心节点的即时依赖。Spring Cloud 文档也明确说明,服务端和客户端都持有内存中的注册信息缓存。citeturn714340view3

这是一种典型的可用性取舍:注册信息不是每一毫秒都绝对新鲜,但调用方在短暂的注册中心故障期间,仍可能依据已有缓存继续发现服务。相应地,网络分区或实例故障时,缓存里也可能暂时保留不可达实例,因此调用端仍要做好超时、重试边界和故障处理。

五、Peer 复制与高可用

生产环境通常不会只放一个 Eureka Server。多个 Server 可以互相配置为 peer,并复制服务注册信息。Spring Cloud 文档指出 Eureka Server 没有后端持久化存储,注册信息主要保存在内存中,客户端也维护本地缓存;因此,高可用需要通过多个 peer、合理的部署拓扑和实例自身的心跳共同实现。citeturn714340view3turn714340view1

这里有个容易踩的认知坑:Peer 复制不等于强一致数据库,也不是共识协议。 网络分区期间,不同节点可能短暂持有不同视图;网络恢复后,节点再通过复制逐步收敛。调用端应该能容忍短时间的实例列表差异,而不是假设所有节点在任意时刻都看到完全相同的注册表。citeturn714340view1

六、自我保护:宁可保留旧记录,也别误删一大片

Eureka 的自我保护机制是它最常被讨论、也最容易被误解的设计之一。

如果大量客户端同时无法续约,原因可能是实例真的集体宕机,也可能只是网络故障、机房隔离或注册中心链路出了问题。此时若 Server 把所有未续约实例立刻清掉,网络恢复后客户端可能拿到一份被误删的空注册表。自我保护的思路是:当续约数量低于预期阈值时,暂停或减少过期实例清理,尽量保留已有注册信息,避免一次网络波动演变成全局服务发现故障。citeturn714340view1turn714340view1

它的代价也很明确:如果实例确实已经宕机,注册表可能会在一段时间内保留过期记录。调用方因此需要快速超时并尝试其他实例;运维侧则要同时看续约率、网络状况和实例健康,而不是只盯着控制台里“保护模式已开启”这一行字。

别把关闭自我保护当作通用修复按钮。 它可能让过期地址清得更快,却也会让网络抖动时的注册表更脆弱。先判断是心跳阈值、实例规模变化、网络分区还是健康检查配置问题,再决定是否调整参数。Eureka 项目文档描述的默认阈值与行为可配置,实际运行值应以部署配置和所用版本为准。citeturn714340view1

七、Spring Cloud Netflix 快速接入

以下示例展示单机开发环境中的最小配置。依赖版本应通过与当前 Spring Boot 版本兼容的 Spring Cloud Release Train 管理,不要把示例里的依赖片段当成可以随手拼版本的许可证。

1. Eureka Server

在 Maven 中添加 Server starter:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

启动类启用 Eureka Server:

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

单机开发环境可以配置为独立 Server,不向自己注册,也不从自己拉取注册表:

server:
  port: 8761

eureka:
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://localhost:8761/eureka/

defaultZone 是 Map 键名,注意大小写;Spring Cloud 文档特别指出它使用 defaultZone 这一大小写形式。citeturn714340view3

2. 业务服务作为 Eureka Client

添加 Client starter:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

配置应用名、端口和 Server 地址:

spring:
  application:
    name: inventory-service

server:
  port: 8081

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

启动应用后,Client starter 会让应用向 Eureka 注册。多个同名实例可以使用相同的 spring.application.name,但实际部署时仍要保证每个实例 ID 唯一。默认配置会结合主机名、应用名和端口生成实例标识;也可以通过 eureka.instance.instanceId 显式覆盖。citeturn714340view3turn714340view3

调用方通过 Spring Cloud LoadBalancer 等组件按服务名选择实例。应用层应调用逻辑服务名,而不是把某个实例 IP 固定写进代码;同时还要配置合理的连接、读取超时和调用失败策略。

八、生产环境里值得提前想清楚的事

多节点与网络拓扑

  • 至少规划多个 Eureka Server,并验证 peer 之间可互通、配置一致。
  • 根据机房或可用区布置节点,尽量让客户端优先使用本地或同区域节点。
  • 明确防火墙、安全组、DNS 和负载均衡的访问路径,避免“端口通了,但 peer 地址不可达”。

实例地址与身份

  • 容器或多网卡环境里要确认注册出去的是调用方实际可达的地址,而不是错误的容器内地址或管理网卡地址。
  • 多实例部署时保证实例 ID 唯一;重复 ID 会让注册记录互相覆盖或产生难以排查的异常行为。
  • 评估优雅停机时的注销过程,并在发布平台上留出摘流与实例退出时间。

健康状态与调用容错

  • 心跳说明客户端仍能和 Eureka 通信,不等同于业务接口一定健康。
  • 注册表更新存在传播延迟,客户端缓存也意味着实例状态不会在所有调用方同时瞬时更新。
  • 调用端仍需设置超时,并根据业务幂等性设计有限重试、熔断或降级;注册中心不能替代这些机制。

可观测性

重点观察注册实例数量、续约成功率、自我保护状态、peer 同步情况、注册表拉取失败,以及业务请求的超时率和实例不可达率。只有把注册中心指标与业务调用指标放在一起看,才能分清“服务没注册上”和“注册了但服务不可用”这两类问题。

九、Eureka 的优势与边界

适合的地方:

  • JVM/Spring Cloud 微服务体系,需要成熟的服务注册与发现集成。
  • 希望客户端使用本地缓存,降低服务发现链路对中心节点的即时依赖。
  • 需要以服务名访问动态变化的实例,并接受短暂的注册信息不一致。

需要权衡的地方:

  • 注册数据主要位于内存中,不提供传统数据库式的持久化注册表。
  • 网络分区时更偏向保留已有注册信息,可能短暂暴露已经失效的实例。
  • 需要自行设计服务调用侧的负载均衡、超时、重试与健康治理。
  • 如果平台已经由 Kubernetes Service、云厂商服务发现或其他控制面统一管理服务地址,再额外引入 Eureka 可能形成两套服务目录,增加运维复杂度。

没有哪个注册中心能脱离部署环境成为“闭眼选”的答案。Eureka 的设计重点是可用性与客户端自治;选型时要把一致性预期、故障模型、生态集成和团队运维能力放在一张桌上比较。

十、总结

Netflix Eureka 做的事很朴素,却是微服务体系的基础设施:服务实例动态注册,客户端按服务名发现实例,缓存和 peer 复制提高了故障场景下的可用性,自我保护则避免网络问题触发大规模误清理。

记住三个要点就够打底:

  1. Eureka 是服务注册与发现组件,不是业务请求的负载均衡器。
  2. 注册信息、缓存和 peer 复制带来可用性,也意味着故障期间可能存在短暂陈旧或不一致的数据。
  3. 自我保护不是“服务健康证明”,客户端仍需要超时、故障处理和可观测性。

把这些边界想明白,再接入 Eureka,系统就不至于把“找得到服务”误当成“服务一定可用”。

参考资料

  • Netflix Eureka 项目 README:Eureka 的定位与用途。citeturn175258search0
  • Netflix Eureka Wiki:自我保护模式、Peer-to-Peer 通信。citeturn175258search1turn714340view1turn714340view1
  • Spring Cloud Netflix 官方参考文档:Eureka Client、Server、注册与高可用配置。citeturn714340view3turn714340view3
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。