Eureka学习笔记-服务端
Eureka学习笔记
服务端
模块设计
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 节点交互。包含以下几个重要的重要组成
- ApplicationsResource:提供全量或增量注册表的获取接口,用于服务发现。
- ApplicationResource:管理特定应用的操作,如实例注册和删除。
- InstanceResource:处理单个实例的操作,如续约、状态更新和详细信息获取。
- PeerReplicationResource:处理 Eureka Server 节点之间的数据复制请求,保证注册表一致性。
- HealthCheckHandler:定义实例健康检查逻辑,决定实例的状态更新。
- EurekaServerResource:提供当前 Eureka Server 的状态和配置信息。
- ClustersResource:管理和查看 Eureka 集群的整体状态和节点信息。
- 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>>>();
InstanceInfo
维护了引用实例的详细信息,主要包含
- instanceId:实例的唯一标识符,用于区分不同的服务实例。
- appName:服务的逻辑名称,便于服务分组和发现。
- vipAddress:虚拟 IP 地址,用于逻辑路由和客户端服务发现。
- status:实例的当前运行状态(如
UP
、DOWN
)。 - lastDirtyTimestamp:实例信息最后一次被修改的时间戳,用于数据冲突判断。
- lastUpdatedTimestamp:实例信息在服务端最后更新的时间戳,用于跟踪本地状态。
- metadata:实例的元数据,存储额外的键值对信息供路由或分组使用。
- hostName:实例的主机名,用于标识和访问实例。
- ipAddr:实例的 IP 地址,用于实例的物理定位。
- leaseInfo:与服务租约相关的信息,如续约间隔和过期时间。
- isDirty:标识实例信息是否处于“脏”状态,用于触发更新。
- actionType:标记实例操作类型(添加、修改、删除)以便同步。
其中lastDirtyTimestamp和lastUpdatedTimestamp看起来很相似实际上二者并不相同
二者对比如下
属性 | 定义 | 用途 | 设置时机 |
---|---|---|---|
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选择放弃强注一致性,来保证即使出现网络分区的情况下,只要客户端可连接上任意一个客户端就可以正常运行。
不同的注册中心产品在一致性的选择上各有千秋,常见的几款产品特性如下
- Eureka(AP系统)
-
牺牲一致性,没有使用严格的一致性协议。
-
最终一致性:Eureka并不要求所有副本在每个时刻都保持一致。在分区恢复时,Eureka会通过心跳和租约机制确保数据最终一致。
-
适用场景:当系统需要高可用性,并且可以容忍短时间的一致性问题时,Eureka非常合适。
- Consul(CP系统)
-
提供强一致性,并使用Raft协议来保证分布式系统的一致性。
-
强一致性:Consul会确保在发生故障或网络分区时,系统的一致性优先。它会牺牲系统的可用性,确保所有的节点看到一致的数据。
-
适用场景:当你需要确保服务注册中心中的数据在所有节点之间保持强一致性时,Consul是一个较好的选择。
- Zookeeper(CP系统)
-
提供强一致性,并使用ZAB协议(Zookeeper Atomic Broadcast)来保证一致性。
-
强一致性:Zookeeper通过分布式共识协议确保数据一致性,因此它在面对网络分区时会牺牲部分可用性。它适用于需要强一致性和协调的应用。
-
适用场景:在需要强一致性的分布式系统中(例如,分布式锁、配置管理等),Zookeeper是一个合适的选项。
- Nacos(AP/CP系统,灵活配置)
-
灵活的可选一致性策略:Nacos可以根据配置调整一致性级别,支持AP模式和CP模式。
-
最终一致性或强一致性:可以通过配置Raft协议来实现一致性保障。默认情况下,Nacos更多的是追求可用性和分区容忍性,但它也支持强一致性模式。
-
适用场景:Nacos适用于需要灵活选择一致性策略的场景,既支持最终一致性,也能在特定场景下实现强一致性。
- 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;...
}
工作流程
被动同步
触发条件
被动同步机制通常在以下情况下触发:
- 节点启动时:Eureka节点启动后,需要与其他节点同步当前服务注册表。
- 节点恢复时:节点在网络分区、宕机等故障恢复后,为确保数据完整性,会从其他节点拉取最新数据。
工作流程
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的操作,即对应用服务的实例做一个随机的打算主要是为了使得每个服务接收的流量更为均匀,同时也是避免新服务启动时出现雪崩现象。
相关文章:

Eureka学习笔记-服务端
Eureka学习笔记 服务端 模块设计 Resources :这部分对外暴露了一系列的 Restful 接口。Eureka Client 的注册、心跳、获取服务列表等操作都需要调用这些接口。另外,其他的 Server 在同步 Registry 时也需要调用这些接口。Controller :这里提…...

无限次使用 cursor pro
github地址 cursor-vip 使用方式 在 MacOS/Linux 中,请打开终端; 在 Windows 中,请打开 Git Bash。 然后执行以下命令来安装: 部分电脑可能会误报毒,需要关闭杀毒软件/电脑管家/安全防护再进行 方式1:通过…...

网站运维之整站同步
网站运维之整站同步 1、使用rsync安装rsync工具子服务器生成密钥子服务器发送公钥到服务端(需要root允许ssh登录)服务端添加密钥子服务器尝试免密登录子服务器添加任务计划 2、开启root用户远程ssh3、ubuntu开启root用户 1、使用rsync 很多时候由于访问…...

【机器人】Graspness 端到端 抓取点估计 | 论文解读
在复杂场景中实现抓取检测,Graspness是一种端到端的方法; 输入点云数据,输出抓取角度、抓取深度、夹具宽度等信息。 开源地址:GitHub - rhett-chen/graspness_implementation: My implementation of Graspnet Graspness. 论文地…...

力扣2300.咒语和药水的成功对数(二分法)
根据 灵茶山艾府 题解所写 题目描述: 给你两个正整数数组 spells 和 potions ,长度分别为 n 和 m ,其中 spells[i] 表示第 i 个咒语的能量强度,potions[j] 表示第 j 瓶药水的能量强度。 同时给你一个整数 success 。一个咒语和药…...

WEB开发: 全栈工程师起步 - Python Flask +SQLite的管理系统实现
一、前言 罗马不是一天建成的。 每个全栈工程师都是从HELLO WORLD 起步的。 之前我们分别用NODE.JS 、ASP.NET Core 这两个框架实现过基于WebServer的全栈工程师入门教程。 今天我们用更简单的来实现: Python。 我们将用Python来实现一个学生管理应用࿰…...

云原生周刊:Kubernetes v1.32 正式发布
开源项目推荐 Helmper Helmper 简化了将 Helm Charts导入OCI(开放容器倡议)注册表的过程,并支持可选的漏洞修复功能。它确保您的 Helm Charts不仅安全存储,还能及时应用最新的安全修复。该工具完全兼容 OCI 标准,能够…...

京准电钟:电厂自控NTP时间同步服务器技术方案
京准电钟:电厂自控NTP时间同步服务器技术方案 京准电钟:电厂自控NTP时间同步服务器技术方案 随着计算机和网络通信技术的飞速发展,火电厂热工自动化系统数字化、网络化的时代已经到来。一方面它为控制和信息系统之间的数据交换、分析和应用…...

深入探索Flink的复杂事件处理CEP
深入探索Flink的复杂事件处理CEP 引言 在当今大数据时代,实时数据处理变得愈发关键。Apache Flink作为一款强大的流处理框架,其复杂事件处理(CEP)组件为我们从海量实时数据中提取有价值信息提供了有力支持。本文将详细介绍Flink…...

clickhouse-数据库引擎
1、数据库引擎和表引擎 数据库引擎默认是Ordinary,在这种数据库下面的表可以是任意类型引擎。 生产环境中常用的表引擎是MergeTree系列,也是官方主推的引擎。 MergeTree是基础引擎,有主键索引、数据分区、数据副本、数据采样、删除和修改等功…...

力扣hot100——哈希
1. 两数之和 class Solution { public:vector<int> twoSum(vector<int>& nums, int target) {vector<int> ans;map<int, int> mp;for (int i 0; i < nums.size(); i) {if (mp.count(target - nums[i])) {ans.push_back(mp[target - nums[i]])…...

少样本学习之CAML算法
上下文感知元学习(Context-Aware Meta-Learning, CAML) 概述 在机器学习和深度学习领域,元学习(Meta-Learning)旨在通过学习如何学习,使模型能够在面对新任务时快速适应。传统的元学习方法通常需要在特定…...

C# 中的闭包
文章目录 前言一、闭包的基本概念二、匿名函数中的闭包1、定义和使用匿名函数2、匿名函数捕获外部变量3、闭包的生命周期 三、Lambda 表达式中的闭包1、定义和使用 Lambda 表达式2、Lambda 表达式捕获外部变量3、闭包的作用域 四、闭包的应用场景1、事件处理2、异步编程3、迭代…...

网络编程 03:端口的定义、分类,端口映射,通过 Java 实现了 IP 和端口的信息获取
一、概述 记录时间 [2024-12-19] 前置文章: 网络编程 01:计算机网络概述,网络的作用,网络通信的要素,以及网络通信协议与分层模型 网络编程 02:IP 地址,IP 地址的作用、分类,通过 …...

制作项目之前的分析
对网页的分析可以从多个角度入手,具体包括内容分析、技术分析、用户体验分析。 以下是对网页分析的详细步骤,帮助你从不同维度评估一个网页的效果与质量: 1. 内容分析 内容是网页最核心的部分,确保其符合用户需求是网页设计的首…...
LeetCode 1925 统计平方和三元组的数目
探索平方和三元组:从问题到 Java 代码实现 在数学与编程的交叉领域,常常会遇到一些有趣且富有挑战性的问题。今天,就让我们深入探讨一下 “平方和三元组” 这个有趣的话题,并使用 Java 语言来实现计算满足特定条件的平方和三元组…...

java开发入门学习三-二进制与其他进制
常见的进制 常用的进制有二进制,八进制,十进制,十六进制。而我们最熟悉的是十进制,他们分别是怎么表达的呢? 定义不同的进制,写法不同 二进制(Binary): 使用前缀 0b 或…...

C/S软件授权注册系统(Winform+WebApi+.NET8+EFCore版)
适用软件:C/S系统、Winform桌面应用软件。 运行平台:Windows .NETCore,.NET8 开发工具:Visual Studio 2022,C#语言 数据库:Microsoft SQLServer 2012,Oracle 21c,MySQL8…...

Linux —— 管理进程
一、查看进程 运行态(Running) 定义:处于运行态的进程正在 CPU 上执行指令。在单 CPU 系统中,同一时刻只有一个进程处于运行态;在多 CPU 或多核系统中,可能有多个进程同时处于运行态。示例: 当…...

Diffusino Policy学习note
Diffusion Policy—基于扩散模型的机器人动作生成策略 - 知乎 建议看看,感觉普通实验室复现不了这种工作。复现了也没有太大扩展的意义。 Diffusion Policy 是监督学习吗 Diffusion Policy 通常被视为一种基于监督学习的方法,但它的实际训练过程可能结…...

【Python】*args和**kwargs
【Python】*args和**kwargs 一、*args: 接收不定数量的位置参数示例1:简单的加法计算器示例2:转发参数给另一个函数 二、**kwargs: 接收不定数量的关键字参数示例3:创建用户配置文件示例4:合并多个字典 三、组合使用*args和**kwar…...

使用正则表达式提取PDF文件页数的实现方案
文章目录 背景介绍实现原理代码实现1. 基础函数结构2. 页数提取逻辑3. 使用示例 正则表达式解析优点与局限性优点局限性 错误处理建议性能优化建议最佳实践建议总结参考资源 背景介绍 在Web应用开发中,我们经常需要获取上传PDF文件的页数信息。虽然可以使用pdf.js等第三方库,但…...

Android实现RecyclerView边缘渐变效果
Android实现RecyclerView边缘渐变效果 1.前言: 是指在RecyclerView中实现淡入淡出效果的边缘效果。通过这种效果,可以使RecyclerView的边缘在滚动时逐渐淡出或淡入,以提升用户体验。 2.Recyclerview属性: 2.1、requiresFading…...

springboot443旅游管理系统(论文+源码)_kaic
摘 要 如今社会上各行各业,都喜欢用自己行业的专属软件工作,互联网发展到这个时候,人们已经发现离不开了互联网。新技术的产生,往往能解决一些老技术的弊端问题。因为传统旅游管理系统信息管理难度大,容错率低&#…...

利用git上传项目到GitHub
GitHub是基于git实现的代码托管。git是目前最好用的版本控制系统了,非常受欢迎,比之svn更好。 GitHub可以免费使用,并且快速稳定。 利用GitHub,你可以将项目存档,与其他人分享交流,并让其他开发者帮助你一…...

Rust之抽空学习系列(四)—— 编程通用概念(下)
Rust之抽空学习系列(四)—— 编程通用概念(下) 1、函数 函数用来对功能逻辑进行封装,能够增强复用、提高代码的可读 以下是函数的主要组成部分: 名称参数返回类型函数体 1.1、函数名称 在Rust中&…...

K-Means 聚类:数据挖掘的瑞士军刀
引言 在数据科学领域,聚类算法是一种非常重要的无监督学习方法,它能够帮助我们发现数据中的自然分组或模式。其中,K-Means 聚类算法因其简单高效而成为最常用的聚类算法之一。无论是市场细分、社交网络分析,还是图像分割等领域&a…...

项目练习:若依-前端项目的目录结构介绍
文章目录 一、目录截图二、目录讲解 一、目录截图 二、目录讲解 1、首先,我们可以看到,这个VUE项目,只有一个App.vue,所以,它是一个单页面系统。 这个App.vue是根组件,root组件。 2、public目录 在Vue 3.…...

知网研学 | 知网文献(CAJ+PDF)批量下载
知网文献(CAJPDF)批量下载 一、知网研学安装二、插件及脚本安装三、CAJ批量下载四、脚本下载及PDF批量下载浏览器取消拦截窗口 一、知网研学安装 批量下载知网文件,格式为es6文件,需使用知网研学软件打开,故需先安装该…...

设计模式期末复习
一、设计模式的概念以及分类 二、设计模式的主题和意图 三、面向对象程序设计原则,记住名字,还要理解它的使用场景以及如何用? 四、松耦合、紧耦合、强关联、弱关联、静态复用、动态复用的概念,还有静态委派,动态委…...