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|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...

大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

《Docker》架构
文章目录 架构模式单机架构应用数据分离架构应用服务器集群架构读写分离/主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构什么是容器,docker,镜像,k8s 架构模式 单机架构 单机架构其实就是应用服务器和单机服务器都部署在同一…...
LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)
在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...
CppCon 2015 学习:Time Programming Fundamentals
Civil Time 公历时间 特点: 共 6 个字段: Year(年)Month(月)Day(日)Hour(小时)Minute(分钟)Second(秒) 表示…...

针对药品仓库的效期管理问题,如何利用WMS系统“破局”
案例: 某医药分销企业,主要经营各类药品的批发与零售。由于药品的特殊性,效期管理至关重要,但该企业一直面临效期问题的困扰。在未使用WMS系统之前,其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...

基于开源AI智能名片链动2 + 1模式S2B2C商城小程序的沉浸式体验营销研究
摘要:在消费市场竞争日益激烈的当下,传统体验营销方式存在诸多局限。本文聚焦开源AI智能名片链动2 1模式S2B2C商城小程序,探讨其在沉浸式体验营销中的应用。通过对比传统品鉴、工厂参观等初级体验方式,分析沉浸式体验的优势与价值…...
Redis——Cluster配置
目录 分片 一、分片的本质与核心价值 二、分片实现方案对比 三、分片算法详解 1. 范围分片(顺序分片) 2. 哈希分片 3. 虚拟槽分片(Redis Cluster 方案) 四、Redis Cluster 分片实践要点 五、经典问题解析 C…...