个人网站

虽然 Eureka 已停更,但它的数据同步机制是 AP 型注册中心的经典设计,面试中仍然高频出现。面试官问这题,不是让你背 Eureka 源码,而是考察你对 分布式数据同步 的理解:多个 Eureka 节点之间怎么保持数据一致?为什么不选强一致?

先说结论

维度 说明
模型 AP(高可用 + 最终一致)
同步方式 Peer to Peer(对等复制)
核心机制 注册 → 复制 → 续约 → 剔除
一致性 最终一致,不保证实时一致
与 ZooKeeper 对比 Eureka 是 AP,ZooKeeper 是 CP

一句话记住:Eureka 的同步像微信群——每个人发消息,其他人都能看到,但可能有延迟;不像电话会议,必须所有人同时在线

Eureka的架构

Service A ──注册──→ Eureka Server 1 ←──复制──→ Eureka Server 2
                        ↑                         ↑
Service B ──注册──→ Eureka Server 1 ←──复制──→ Eureka Server 2

Service C ──拉取──→ Eureka Server 1(获取所有服务列表)
  • 所有 Eureka Server 节点 地位平等,没有主从之分
  • 服务注册到任意一个节点,数据会 复制到其他节点
  • 客户端从任意一个节点拉取注册表

数据同步的四个阶段

阶段一:服务注册

服务启动时,向 Eureka Server 发送注册请求:

// 服务端处理注册
public void register(InstanceInfo info, boolean isReplication) {
    registry.register(info, leaseDuration, isReplication);
    // 👈 isReplication 标记是否是复制来的请求
    if (!isReplication) {
        replicateToPeers("register", info);  // 👈 不是复制来的,才向其他节点复制
    }
}

关键点:isReplication 标记——如果是其他节点复制过来的注册信息,不再继续向其他节点复制,避免无限循环。

阶段二:Peer to Peer复制

Eureka Server 之间是对等复制:

private void replicateToPeers(String action, InstanceInfo info) {
    for (PeerEurekaNode peer : peerEurekaNodes) {
        // 👈 向每个对等节点复制
        peer.replicate(action, info);
    }
}

复制是 异步 的——注册请求先本地成功,再异步复制到其他节点。这意味着:

  • 注册成功后,其他节点可能还看不到新服务
  • 但最终所有节点的数据会一致(最终一致性)

阶段三:心跳续约

服务每 30 秒向 Eureka Server 发送心跳:

// 客户端定时发送心跳
@Scheduled(fixedRate = 30000)
public void heartbeat() {
    eurekaClient.sendHeartBeat(instanceInfo);
}

Eureka Server 如果 90 秒没收到心跳,就认为服务不可用,将其从注册表中 剔除

心跳也有复制——Server A 收到心跳后,异步复制到 Server B。

阶段四:注册表拉取

客户端每 30 秒从 Eureka Server 拉取完整注册表(首次)或增量注册表(后续):

// 增量拉取
Applications delta = eurekaClient.getDelta();
// 👈 只获取最近 3 分钟内变化的实例

增量拉取只返回最近变化的部分,减少网络开销。但增量数据可能丢失,所以 Eureka 会定期(每 6 次)全量拉取一次对齐。

为什么Eureka选择AP而不是CP

场景 CP(ZooKeeper) AP(Eureka)
网络分区 选主期间不可用 继续提供服务
节点故障 重新选主,期间不可用 其他节点照常工作
数据一致性 强一致 最终一致
适用场景 强依赖一致性的场景 服务发现场景

服务发现场景为什么选 AP?

假设网络分区发生,ZooKeeper 会选主,选主期间注册中心不可用——你连注册中心都连不上,更别提发现服务了。

Eureka 的选择:即使数据暂时不一致(某些节点看到的注册表不同),也要保证可用——你能发现服务,虽然可能发现的是过期的服务。这在微服务场景中更可接受,因为调用方本身就有重试和超时机制。

Eureka的自我保护机制

当 Eureka Server 在短时间内丢失大量心跳(超过 85%),它认为可能是网络问题而非服务真的挂了,进入 自我保护模式

  • 不再剔除过期服务
  • 继续对外提供服务注册和发现
  • 网络恢复后自动退出

这避免了"网络抖动导致大量服务被误剔除"的问题。

Eureka 数据同步全景

架构模型
├── Peer to Peer(对等复制)
├── AP 模型(高可用 + 最终一致)
└── 无主架构(所有节点平等)

同步流程
├── 注册 → 本地保存 → 异步复制到 Peer
├── 心跳 → 本地续约 → 异步复制到 Peer
├── 剔除 → 90秒无心跳 → 本地剔除
└── 拉取 → 增量 + 定期全量对齐

核心设计
├── isReplication 防循环复制
├── 异步复制(最终一致)
├── 自我保护(防误剔除)
└── 增量拉取 + 全量对齐

口诀:Peer to Peer对等网,注册复制异步走;
      心跳续约三十秒,九十不跳就剔除;
      自我保护防误判,增量拉取省带宽;
      AP模型保可用,最终一致是代价

回答技巧与点评

标准回答:Eureka Server 采用 Peer to Peer 对等复制模型,服务注册到任意节点后,异步复制到其他对等节点。核心机制包括:注册(isReplication 防循环复制)、心跳续约(30秒一次,90秒超时剔除)、增量拉取(客户端每30秒拉取变化数据)。Eureka 选择 AP 模型,保证高可用,牺牲强一致性,网络分区时仍可提供服务发现。自我保护机制在心跳丢失过多时暂停剔除,防止误判。

加分回答

  1. isReplication 的精妙:注册请求携带 isReplication 标记,只在首次注册时向其他节点复制,避免 A→B→A 的无限循环。这是分布式系统中防止消息风暴的经典做法
  2. Read-Write Cache:Eureka Server 使用两级缓存(ReadWriteCacheMap + ReadOnlyCacheMap),读操作走 ReadOnly 缓存(每30秒同步一次),写操作更新 ReadWrite 缓存。这是典型的 读写分离 优化
  3. Nacos 的改进:Nacos 支持 AP/CP 模式切换——临时实例用 AP(类似 Eureka),持久化实例用 CP(Raft 协议)。比 Eureka 更灵活

面试官点评

这道题考的是你对 分布式一致性模型 的理解。能说出 Peer to Peer 复制和 AP 模型算及格,高分的关键在于:解释为什么服务发现选 AP 而不是 CP,以及 isReplication 防循环复制的机制。如果你能把 Eureka 的两级缓存也讲出来,说明你看过源码。

原文阅读


内容有帮助?点赞、收藏、关注三连!评论区等你 💪

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐