孤舟笔记 Spring全家桶篇二十五 谈谈EurekaServer数据同步原理?注册中心怎么保证数据一致性

文章目录

个人网站

虽然 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 发送注册请求:

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

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

阶段二:Peer to Peer复制

Eureka Server 之间是对等复制:

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

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

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

阶段三:心跳续约

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

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

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

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

阶段四:注册表拉取

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

java 复制代码
// 增量拉取
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 的两级缓存也讲出来,说明你看过源码。

原文阅读


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

相关推荐
落魄江湖行17 小时前
孤舟笔记 互联网常用框架篇三 Dubbo是如何动态感知服务下线的?注册中心和服务端双保险
春招·孤舟笔记·dubbo是如何动态感知服务下
落魄江湖行17 天前
孤舟笔记 IO 与网络编程篇三 IO和NIO的区别是什么?从阻塞到非阻塞的范式革命
春招·孤舟笔记·io和nio的区别
落魄江湖行22 天前
孤舟笔记 并发篇十八 为什么启动线程不能直接调用run()方法?调用两次start()又会怎样?这个设计藏着大智慧
thread·java并发·春招·孤舟笔记
逻辑驱动的ken22 天前
Java高频面试考点场景题22
java·开发语言·jvm·面试·职场和发展·求职招聘·春招
落魄江湖行22 天前
孤舟笔记 并发篇二十九 volatile关键字有什么用?它的实现原理是什么?面试必问的轻量级同步机制
java并发·春招·孤舟笔记·volatile关键字
落魄江湖行23 天前
孤舟笔记 并发篇二十八 wait和sleep是否会触发锁的释放及CPU资源的释放?这个区别面试必考
java并发·春招·孤舟笔记·wait和sleep
落魄江湖行23 天前
孤舟笔记 并发篇二十二 线程池是如何回收线程的?核心线程和非核心线程的回收逻辑大不相同
java并发·春招·孤舟笔记·线程池是如何回收线程的
落魄江湖行24 天前
孤舟笔记 并发篇二十五 当任务数超过核心线程数时,如何让任务不进入队列?线程池调优的经典问题
java并发·春招·孤舟笔记·当任务数超过核心线程数时
落魄江湖行24 天前
孤舟笔记 并发篇二十三 线程池是如何实现线程复用的?Worker循环取任务的秘密远比你想象的精巧
java并发·春招·孤舟笔记