Eureka学习笔记-服务端

ops/2024/12/19 5:44:08/

Eureka学习笔记

服务端

模块设计

bc5ce85ee28b1b4fab72e7adbcc719ea

  • Resources :这部分对外暴露了一系列的 Restful 接口。Eureka Client 的注册、心跳、获取服务列表等操作都需要调用这些接口。另外,其他的 Server 在同步 Registry 时也需要调用这些接口。
  • Controller :这里提供了几个 web 接口,主要用在 Eureka Server 本身的 Dashboard 页面, 从页面上可以查看到当前注册了的服务,以及每个服务下各个实例的状态。
  • PeerAwareInstanceRegistry :这里面记录了当前所以注册了的服务实例。当这些注册信息发生变化时,`PeerAwareInstanceRegistry 还要负责把这些变化同步到其他的 Server。
  • PeerEurekaNodes :这里维护了集群里所有 Eureka Server 节点的信息,PeerAwareInstanceRegistry 在同步时需要从这里获取其他 Server 的信息。同时它还负责定时检查配置来发现是否有 Eureka Server 节点新增或删除。
  • HttpReplicationClient :这是 PeerAwareInstanceRegistry 向其他 Server 同步时发送请求的 http client。
Resources

Eureka Service 的 Resource 是指处理 Eureka Server 提供的各类 RESTful API 的类,主要负责与客户端和其他 Eureka Server 节点交互。包含以下几个重要的重要组成

  1. ApplicationsResource:提供全量或增量注册表的获取接口,用于服务发现。
  2. ApplicationResource:管理特定应用的操作,如实例注册和删除。
  3. InstanceResource:处理单个实例的操作,如续约、状态更新和详细信息获取。
  4. PeerReplicationResource:处理 Eureka Server 节点之间的数据复制请求,保证注册表一致性。
  5. HealthCheckHandler:定义实例健康检查逻辑,决定实例的状态更新。
  6. EurekaServerResource:提供当前 Eureka Server 的状态和配置信息。
  7. ClustersResource:管理和查看 Eureka 集群的整体状态和节点信息。
  8. ServerCodecs:定义注册表数据的编码和解码规则,支持 JSON 和 XML 格式。
AbstractInstanceRegistry
register

其内部维护了一个如下的Map结构,key为应用标识,value同样是一个Map,后者的key为单个应用实例的标识,value为单个实例的详细信息(被Lease包装了实例的租期信息)

private final ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>> registry= new ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>>();

image-20241213223912222

InstanceInfo

维护了引用实例的详细信息,主要包含

  • instanceId:实例的唯一标识符,用于区分不同的服务实例。
  • appName:服务的逻辑名称,便于服务分组和发现。
  • vipAddress:虚拟 IP 地址,用于逻辑路由和客户端服务发现。
  • status:实例的当前运行状态(如 UPDOWN)。
  • lastDirtyTimestamp:实例信息最后一次被修改的时间戳,用于数据冲突判断。
  • lastUpdatedTimestamp:实例信息在服务端最后更新的时间戳,用于跟踪本地状态。
  • metadata:实例的元数据,存储额外的键值对信息供路由或分组使用。
  • hostName:实例的主机名,用于标识和访问实例。
  • ipAddr:实例的 IP 地址,用于实例的物理定位。
  • leaseInfo:与服务租约相关的信息,如续约间隔和过期时间。
  • isDirty:标识实例信息是否处于“脏”状态,用于触发更新。
  • actionType:标记实例操作类型(添加、修改、删除)以便同步。

其中lastDirtyTimestamplastUpdatedTimestamp看起来很相似实际上二者并不相同

二者对比如下

属性定义用途设置时机
lastUpdatedTimestamp服务端记录实例信息最后更新时间服务端内部维护,用于跟踪当前实例的更新情况Eureka Server 自动设置
lastDirtyTimestamp客户端记录实例信息最后一次被修改时间戳数据冲突判断与同步传播,表示数据的新旧状态Eureka Client 或服务端同步时设置
Lease
public class Lease<T> {// 注册、下线、续期enum Action {Register, Cancel, Renew};// 默认驱逐时间public static final int DEFAULT_DURATION_IN_SECS = 90;// 持有的应用实例的引用private T holder;// 被驱逐时间private long evictionTimestamp;// 服务注册时间private long registrationTimestamp;// 服务完全可用时间private long serviceUpTimestamp;// 最后续租时间private volatile long lastUpdateTimestamp;
}
驱逐机制

我们可以看到每个实例都被Lease包装,其中就记录着实例的注册时间registrationTimestamp,以及最后续租时间lastUpdateTimestamp,当实例没有在驱逐超时时间内完成续租将会被驱逐,后者由定时任务EvictionTask来来完成

class EvictionTask extends TimerTask {private final AtomicLong lastExecutionNanosRef = new AtomicLong(0l);@Overridepublic void run() {try {long compensationTimeMs = getCompensationTimeMs();logger.info("Running the evict task with compensationTime {}ms", compensationTimeMs);evict(compensationTimeMs);} catch (Throwable e) {logger.error("Could not run the evict task", e);}}
}
PeerEurekaNodes

PeerEurekaNodes 是一个整体管理类,内部包含多个 PeerEurekaNode 实例,每个实例代表一个集群节点。

其中一个重要的功能便是定时同步集群的节点信息,这个任务由其start()法方法中的定时器完成

public void start() {...updatePeerEurekaNodes(resolvePeerUrls());...taskExecutor.scheduleWithFixedDelay(peersUpdateTask,serverConfig.getPeerEurekaNodesUpdateIntervalMs(),serverConfig.getPeerEurekaNodesUpdateIntervalMs(),TimeUnit.MILLISECONDS);...
}

一致性设计

Eureka 是一个AP系统,本身没有采用任何一种强一致性协议来保证系统整体的强一致性,根据CAP定理,一致性、可以用、分区可容忍性三者不可兼得,Eureka选择放弃强注一致性,来保证即使出现网络分区的情况下,只要客户端可连接上任意一个客户端就可以正常运行。

不同的注册中心产品在一致性的选择上各有千秋,常见的几款产品特性如下

  1. Eureka(AP系统)
  • 牺牲一致性,没有使用严格的一致性协议。

  • 最终一致性:Eureka并不要求所有副本在每个时刻都保持一致。在分区恢复时,Eureka会通过心跳和租约机制确保数据最终一致。

  • 适用场景:当系统需要高可用性,并且可以容忍短时间的一致性问题时,Eureka非常合适。

    1. Consul(CP系统)
  • 提供强一致性,并使用Raft协议来保证分布式系统的一致性。

  • 强一致性:Consul会确保在发生故障或网络分区时,系统的一致性优先。它会牺牲系统的可用性,确保所有的节点看到一致的数据。

  • 适用场景:当你需要确保服务注册中心中的数据在所有节点之间保持强一致性时,Consul是一个较好的选择。

  1. Zookeeper(CP系统)
  • 提供强一致性,并使用ZAB协议(Zookeeper Atomic Broadcast)来保证一致性。

  • 强一致性:Zookeeper通过分布式共识协议确保数据一致性,因此它在面对网络分区时会牺牲部分可用性。它适用于需要强一致性和协调的应用。

  • 适用场景:在需要强一致性的分布式系统中(例如,分布式锁、配置管理等),Zookeeper是一个合适的选项。

    1. Nacos(AP/CP系统,灵活配置)
  • 灵活的可选一致性策略:Nacos可以根据配置调整一致性级别,支持AP模式和CP模式。

  • 最终一致性或强一致性:可以通过配置Raft协议来实现一致性保障。默认情况下,Nacos更多的是追求可用性和分区容忍性,但它也支持强一致性模式。

  • 适用场景:Nacos适用于需要灵活选择一致性策略的场景,既支持最终一致性,也能在特定场景下实现强一致性。

  1. Etcd(CP系统)
  • 提供强一致性,并使用Raft协议保证数据一致性。
  • 强一致性:Etcd优先考虑一致性,在网络分区或节点故障时,它会保持一致性,并且牺牲部分可用性。
  • 适用场景:当分布式系统对一致性要求非常高时,Etcd是非常合适的。它常用于服务发现、配置管理和分布式协调等场景。

同步数据设计

数据同步的关键技术要点
  • REST API:Eureka集群通过HTTP REST API进行节点间的通信与数据同步。每个Eureka节点向其他节点推送自己更新的服务信息。
  • PeerAwareReplication:该机制是Eureka集群的核心,负责将服务注册信息在节点之间进行复制。每个节点知道其他节点的存在,并能够主动或被动地同步服务数据。
  • 心跳和租约机制:服务实例通过发送心跳请求来续约租约,确保服务实例不会因未能及时续约而被误删。租约过期的信息也会在节点间同步。
  • 最终一致性:Eureka采用最终一致性模型,而不是强一致性。在网络分区或节点故障时,系统可以继续运行,但在恢复后,系统会进行数据同步,直到一致性最终达成。
主动同步
触发条件

Eureka节点会在服务注册、续约、注销等事件发生时主动将变化的信息推送到其他节点。

PeerAwareInstanceRegistryImpl#replicateToPeers()

private void replicateToPeers(Action action, String appName, String id,InstanceInfo info /* optional */,InstanceStatus newStatus /* optional */, boolean isReplication) {Stopwatch tracer = action.getTimer().start();try {// 是否是一个复制请求if (isReplication) {numberOfReplicationsLastMin.increment();}...for (final PeerEurekaNode node : peerEurekaNodes.getPeerEurekaNodes()) {// 是否来自自身,如何是则跳过if (peerEurekaNodes.isThisMyUrl(node.getServiceUrl())) {continue;}// 复制同步到对等节点replicateInstanceActionsToPeers(action, appName, id, info, newStatus, node);}} finally {tracer.stop();}
}
private void replicateInstanceActionsToPeers(Action action, String appName,String id, InstanceInfo info, InstanceStatus newStatus,PeerEurekaNode node) {...switch (action) {case Cancel:node.cancel(appName, id);break;case Heartbeat:InstanceStatus overriddenStatus = overriddenInstanceStatusMap.get(id);infoFromRegistry = getInstanceByAppAndId(appName, id, false);node.heartbeat(appName, id, infoFromRegistry, overriddenStatus, false);break;case Register:node.register(info);break;...
}
工作流程

image-20241214212242280

被动同步
触发条件

被动同步机制通常在以下情况下触发:

  • 节点启动时:Eureka节点启动后,需要与其他节点同步当前服务注册表。
  • 节点恢复时:节点在网络分区、宕机等故障恢复后,为确保数据完整性,会从其他节点拉取最新数据。
工作流程

image-20241213214821801
DiscoveryClient#getAndStoreFullRegistry()

private void getAndStoreFullRegistry() throws Throwable {long currentUpdateGeneration = fetchRegistryGeneration.get();logger.info("Getting all instance registry info from the eureka server");// 从其他Eureka Service 获取ApplicationsApplications apps = null;EurekaHttpResponse<Applications> httpResponse = clientConfig.getRegistryRefreshSingleVipAddress() == null? eurekaTransport.queryClient.getApplications(remoteRegionsRef.get()): eurekaTransport.queryClient.getVip(clientConfig.getRegistryRefreshSingleVipAddress(), remoteRegionsRef.get());if (httpResponse.getStatusCode() == Status.OK.getStatusCode()) {apps = httpResponse.getEntity();}...localRegionApps.set(this.filterAndShuffle(apps));
}
private Applications filterAndShuffle(Applications apps) {if (apps != null) {...if (isFetchingRemoteRegionRegistries()) {Map<String, Applications> remoteRegionVsApps = new ConcurrentHashMap<String, Applications>();apps.shuffleAndIndexInstances(remoteRegionVsApps, clientConfig, instanceRegionChecker);for (Applications applications : remoteRegionVsApps.values()) {applications.shuffleInstances(clientConfig.shouldFilterOnlyUpInstances());}}...}
}

我们可以看到之类有一个shuffle的操作,即对应用服务的实例做一个随机的打算主要是为了使得每个服务接收的流量更为均匀,同时也是避免新服务启动时出现雪崩现象。


http://www.ppmy.cn/ops/143090.html

相关文章

学习日志024--opencv中处理轮廓的函数

目录 前言​​​​​​​ 一、 梯度处理的sobel算子函数 功能 参数 返回值 代码演示 二、梯度处理拉普拉斯算子 功能 参数 返回值 代码演示 三、Canny算子 功能 参数 返回值 代码演示 四、findContours函数与drawContours函数 功能 参数 返回值 代码演示 …

知乎 PB 级别 TiDB 数据库集群管控实践

以下文章来源于知乎技术专栏 &#xff0c;作者代晓磊 导读 在现代企业中&#xff0c;数据库的运维管理至关重要&#xff0c;特别是面对分布式数据库的复杂性和大规模集群的挑战。作为一款兼容 MySQL 协议的分布式关系型数据库&#xff0c;TiDB 在高可用、高扩展性和强一致性方…

如何在Qt中应用html美化控件

在Qt中应用HTML美化控件&#xff0c;主要可以通过以下几种方式&#xff1a; 使用QWebEngineView&#xff1a;QWebEngineView是基于Chromium引擎的控件&#xff0c;用于显示和交互HTML内容。它支持现代Web标准和技术&#xff0c;如HTML5、CSS3和JavaScript。你可以通过以下步骤…

使用Flinkcdc 采集mysql数据

1.下载 Flink CDC 连接器 &#xff08;1&#xff09;登录官网下载 https://github.com/apache/flink-cdc/releases &#xff08;1&#xff09;或者虚拟机在线下载 wget https://repo1.maven.org/maven2/com/ververica/flink-sql-connector-mysql-cdc/2.2.1/flink-sql-connecto…

基于Vue的乐器教学平台的设计与实现

一、前言 随着互联网技术的飞速发展&#xff0c;在线教育逐渐成为一种重要的教育方式。乐器教学作为艺术教育的重要组成部分&#xff0c;也迎来了新的机遇与挑战。传统的乐器教学主要依赖于面对面授课&#xff0c;受时间、空间和师资资源的限制较大。而开发一个基于 Vue 的乐器…

机器学习基础环境安装与使用

目录 A Neural Network Playground 1、库的安装 2、Jupyter Notebook使用 2.1、快捷键操作 2.2、markdown语法 2.3、安装jupyter_contrib_nbextension库 A Neural Network Playground 1、库的安装 整个机器学习基础阶段会用到Matplotlib、Numpy、Pandas等等,为了统一版…

const和修饰指针的几种用法

昨天闲着没事去面试了一个C岗位&#xff0c;问了很多基础的东西都没答上来。主要原因是这些知识在硬件资源丰富的pc端用的不多&#xff0c;二来确实很久没温习之前的C相关的知识了。在面试官问了几次类似的问题没有答好的情况下&#xff08;还喜欢问你确不确定&#xff09;&…

opencv礼帽和黑帽运算

礼帽 原始输入 - 开运算结果&#xff0c;留存的以白色毛刺为主 黑帽 闭运算 - 原始输入&#xff0c;保留的更多是原始轮廓 # 导入OpenCV库&#xff0c;用于图像处理 import cv2 import numpy as np # 从matplotlib库中导入pyplot模块&#xff0c;用于绘制图像 from …