当前位置: 首页 > news >正文

Eureka 学习笔记5:InstanceRegistry

版本 awsVersion = ‘1.11.277’

InstanceRegistry


LeaseManager 接口管理实例的租约信息,提供以下功能:

  1. 注册实例
  2. 取消注册实例
  3. 实例续约
  4. 剔除过期实例
public interface LeaseManager<T> {/** 注册实例并续约*/void register(T r, int leaseDuration, boolean isReplication);/*** 取消注册实例*/boolean cancel(String appName, String id, boolean isReplication);/*** 续约*/boolean renew(String appName, String id, boolean isReplication);/*** 剔除过期实例*/void evict();
}

InstanceRegistry 接口即注册表服务,继承 LeaseManager 接口,提供以下功能:

  1. 启动和关闭注册表服务
  2. 更新注册表中实例的状态
  3. 从注册表中获取应用信息和实例信息
  4. 初始化和获取注册表缓存
  5. 租约过期机制和自我保护机制(和 LeaseManager 的 evict() 方法相关)
public interface InstanceRegistry extends LeaseManager<InstanceInfo>, LookupService<String> {// ========================// 启动和关闭注册表服务// ========================/*** 在PeerAwareInstanceRegistry接口的init()和syncUp()方法调用后被调用* 1.更新expectedNumberOfClientsSendingRenews*   更新numberOfRenewsPerMinThreshold* 2.如果从其他Eureka节点拉取注册表成功并且实例数量大于0*   设置peerInstancesTransferEmptyOnStartup为false*   和PeerAwareInstanceRegistry接口的shouldAllowAccess()方法相关* 3.设置startupTime为当前时间* 4.设置自身实例状态为InstanceStatus.UP* 5.调用postInit()方法*   创建EvictionTask并通过Timer调度定时剔除过期实例*   配置evictionIntervalTimerInMs指定剔除过期实例的时间间隔,默认60s*/void openForTraffic(ApplicationInfoManager applicationInfoManager, int count);void shutdown();// ========================// 更新注册表中实例的状态// ========================@Deprecatedvoid storeOverriddenStatusIfRequired(String id, InstanceStatus overriddenStatus);/*** 更新注册表中实例的overriddenStatus*/void storeOverriddenStatusIfRequired(String appName, String id, InstanceStatus overriddenStatus);/*** 更新注册表中实例的overriddenStatus和status*/boolean statusUpdate(String appName,String id,InstanceStatus newStatus,String lastDirtyTimestamp,boolean isReplication);/*** 删除注册表中实例的overriddenStatus并设置status*/boolean deleteStatusOverride(String appName,String id,InstanceStatus newStatus,String lastDirtyTimestamp,boolean isReplication);/*** 获取注册表中overriddenStatus集合的快照*/Map<String, InstanceStatus> overriddenInstanceStatusesSnapshot();// ========================// 注册表 CRUD// ========================/*** 获取本地注册表*/Applications getApplicationsFromLocalRegionOnly();/*** 根据应用名称从本地注册表或其他region的注册表中获取应用信息*/Application getApplication(String appName, boolean includeRemoteRegion);/*** 根据应用名称和实例id从本地注册表或其他region的注册表中获取实例信息*/InstanceInfo getInstanceByAppAndId(String appName, String id);/*** 根据应用名称和实例id从本地注册表或其他region的注册表中获取实例信息*/InstanceInfo getInstanceByAppAndId(String appName, String id, boolean includeRemoteRegions);/*** 清空注册表*/void clearRegistry();// ========================// 注册表缓存// ========================/*** 初始化注册表缓存ResponseCacheImpl*/void initializedResponseCache();/*** 获取注册表缓存ResponseCacheImpl*/ResponseCache getResponseCache();// ========================// 租约过期机制&自我保护机制// ========================/*** 获取上一分钟收到的续约(renew)请求数*/long getNumOfRenewsInLastMin();/*** 获取每一分钟续约(renew)请求数的阈值* 如果上一分钟收到的续约请求数小于阈值,开启自我保护机制* 计算方式:实例数量 * (60 / 续约间隔时间)* 续约百分比阈值0.85* this.expectedNumberOfClientsSendingRenews * *     (60.0 / serverConfig.getExpectedClientRenewalIntervalSeconds()) **     serverConfig.getRenewalPercentThreshold())*/int getNumOfRenewsPerMinThreshold();/*** 是否启用租约过期机制*/boolean isLeaseExpirationEnabled();/*** 是否启用自我保护机制*/boolean isSelfPreservationModeEnabled();
}

Map<String, RemoteRegionRegistry> regionNameVSRemoteRegistry 是 AbstractInstanceRegistry 抽象类的成员变量,key 是 remoteRegionUrlsWithName 配置中的 regionName,value 则是 initRemoteRegionRegistry() 方法中创建的RemoteRegionRegistry 对象。

// 配置remoteRegionUrlsWithName 
regionName1;regionUrl1,regionName2;regionUrl2...

RemoteRegionRegistry 类表示其他区域的注册表信息,配置 remoteRegion.registryFetchIntervalInSeconds 指定从其他区域拉取注册表信息的间隔时间,默认 30s

拉取成功后,将 readyForServingData 设置为 true,表示该区域的注册表已经可以提供服务。

Runnable remoteRegionFetchTask = new Runnable() {@Overridepublic void run() {try {if (fetchRegistry()) {readyForServingData = true;} else {logger.warn("Failed to fetch remote registry. " +"This means this eureka server " + "is not ready for serving traffic.");}}}
};scheduler.schedule(new TimedSupervisorTask("RemoteRegionFetch_" + regionName,scheduler,remoteRegionFetchExecutor,// 配置remoteRegion.registryFetchIntervalInSecondsserverConfig.getRemoteRegionRegistryFetchInterval(),TimeUnit.SECONDS,5,  // exponential backoff boundremoteRegionFetchTask),serverConfig.getRemoteRegionRegistryFetchInterval(),TimeUnit.SECONDS);

remoteRegion.global.appWhiteListremoteRegion.{regionName}.appWhiteList 配置全局和 regionName 指定区域的拉取白名单,appName 不在白名单中的应用信息是无法拉取的。


PeerAwareInstanceRegistry 接口继承 InstanceRegistry 接口,提供以下功能:

public interface PeerAwareInstanceRegistry extends InstanceRegistry {/*** 初始化PeerAwareInstanceRegistryImpl,包括:*     1.实例化注册表缓存ResponseCacheImpl*     2.创建定时任务,定时更新numberOfRenewsPerMinThreshold*         配置renewalThresholdUpdateIntervalMs*         指定更新numberOfRenewsPerMinThreshold的时间间隔,默认15min*     3.初始化其他区域注册表regionNameVSRemoteRegistry*/void init(PeerEurekaNodes peerEurekaNodes) throws Exception;/*** 是否可以对外提供注册表服务*     1.如果在调用openForTraffic方法时*       从其他Eureka节点拉取注册表失败则返回false*     2.如果remoteRegionRequired为true*       还需要等待其他区域注册表全部拉取成功后才返回true*/boolean shouldAllowAccess(boolean remoteRegionRequired);/*** 从其他Eureka节点拉取注册表信息*/int syncUp();/*** 注册实例信息*/void register(InstanceInfo info, boolean isReplication);void statusUpdate(final String asgName,final ASGResource.ASGStatus newStatus,final boolean isReplication);
}

:在 LeaseManager 接口中已经声明了 register(T r, int leaseDuration, boolean isReplication) 方法的前提下,为什么在 PeerAwareInstanceRegistry 接口中再次声明 register(InstanceInfo info, boolean isReplication) 方法呢?原来 register(InstanceInfo info, boolean isReplication) 方法是在 syncUp() 方法中被调用,是将从其他 Eureka 节点拉取过来的注册表中的实例信息注册到本地注册表中

// com.netflix.eureka.registry.PeerAwareInstanceRegistryImpl
public int syncUp() {// 统计从其他Eureka节点同步过来的实例信息数量int count = 0;// ...// 从其他Eureka节点拉取注册表信息Applications apps = eurekaClient.getApplications();for (Application app : apps.getRegisteredApplications()) {for (InstanceInfo instance : app.getInstances()) {// ...// 判断该实例的availabilityZone是否和当前Eureka节点属于同一个region// 如果是,则将该实例注册到本地注册表if (isRegisterable(instance)) {register(instance,instance.getLeaseInfo().getDurationInSecs(),true);count++;}} }// ...return count;
}

PeerAwareInstanceRegistryImpl 类构造方法和 init 方法代码如下:

@Singleton
public class PeerAwareInstanceRegistryImplextends AbstractInstanceRegistryimplements PeerAwareInstanceRegistry {// startupTime、peerInstancesTransferEmptyOnStartup// 在openForTraffic方法被调用时赋值private long startupTime = 0;private boolean peerInstancesTransferEmptyOnStartup = true;// peerEurekaNodes在init方法被调用时赋值protected volatile PeerEurekaNodes peerEurekaNodes;// eurekaClient在构造方法被调用时赋值protected final EurekaClient eurekaClient;// instanceStatusOverrideRule在构造方法被调用时赋值private final InstanceStatusOverrideRule instanceStatusOverrideRule;// 定时调用updateRenewalThreshold方法private Timer timer = new Timer("ReplicaAwareInstanceRegistry - RenewalThresholdUpdater", true);@Injectpublic PeerAwareInstanceRegistryImpl(EurekaServerConfig serverConfig,EurekaClientConfig clientConfig,ServerCodecs serverCodecs,EurekaClient eurekaClient) {super(serverConfig, clientConfig, serverCodecs);this.eurekaClient = eurekaClient;this.numberOfReplicationsLastMin = new MeasuredRate(1000 * 60 * 1);// We first check if the instance is STARTING or DOWN,// then we check explicit overrides,// then we check the status of a potentially existing lease.this.instanceStatusOverrideRule =new FirstMatchWinsCompositeRule(new DownOrStartingRule(),new OverrideExistsRule(overriddenInstanceStatusMap),new LeaseExistsRule());}@Overridepublic void init(PeerEurekaNodes peerEurekaNodes) throws Exception {// 1.统计每分钟和其他Eureka节点的同步频率this.numberOfReplicationsLastMin.start();// 2.赋值peerEurekaNodes属性,保存Eureka集群节点信息this.peerEurekaNodes = peerEurekaNodes;// 3.创建本地注册表缓存ResponseCacheImplinitializedResponseCache();// 4.创建TimerTask,通过Timer调度updateRenewalThreshold方法// 定时更新numberOfRenewsPerMinThresholdscheduleRenewalThresholdUpdateTask();// 5.创建其他区域的注册表RemoteRegionRegistryinitRemoteRegionRegistry();// ...}
}
  1. 实现了 PeerAwareInstanceRegistry 接口,通过 eurekaClient 属性获得了从其他 Eureka 节点拉取注册表(PeerAwareInstanceRegistry#syncUp()方法)的能力,

  2. 通过 peerEurekaNodes 属性获得了将本地注册表的更新同步给其他 Eureka 节点(PeerAwareInstanceRegistryImpl#replicateToPeers()方法)的能力

:为什么不将 Eureka 节点之间同步更新数据的操作和拉取注册表的操作一起声明在 PeerAwareInstanceRegistry 接口中,而是另外通过 PeerEurekaNode 类去实现呢?

既然 numberOfRenewsPerMinThreshold 是通过实例数量实时计算为什么不将 numberOfRenewsPerMinThreshold 属性声明在 PeerAwareInstanceRegistryImpl 类中,而是声明在父类 AbstractInstanceRegistry 中?

instanceStatusOverrideRule 根据规则计算实例的

相关文章:

Eureka 学习笔记5:InstanceRegistry

版本 awsVersion ‘1.11.277’ LeaseManager 接口管理实例的租约信息&#xff0c;提供以下功能&#xff1a; 注册实例取消注册实例实例续约剔除过期实例 public interface LeaseManager<T> {/** 注册实例并续约*/void register(T r, int leaseDuration, boolean isRep…...

System Verilog——虚方法的使用

1、使用虚方法目的 通过在父类里定义虚方法(task or function)&#xff0c;可以在当父类句柄调用一个方法时候&#xff0c;前提是若是这个句柄指向了子类对象&#xff0c;则调用的方法为子类的方法而不是父类的方法。 1.1、实例理解&#xff1a;将子类句柄赋值成父类句柄 mod…...

线性规划和单纯形法-原理篇

文章目录 引言线性规划标准型问题特点单纯形法 引言 很多运筹学的教材都是从线性规划开始的&#xff0c;我平时做算法策略的落地应用时也研发了一部分基于线性规划的技术方案。可以说&#xff0c;如果搞不懂线性规划&#xff0c;很难成为一名优秀的运筹优化算法工程师。 但是…...

FBX SDK开发快速上手指南

一段时间以来&#xff0c;我一直想制作一个 FBX Exporter 将 FBX 文件转换为我自己的格式。 整个过程不是很顺利&#xff0c;主要是FBX的官方文档不是很清楚。 另外&#xff0c;由于 FBX 格式被许多应用程序使用&#xff0c;而不仅仅是游戏引擎&#xff0c;因此提供的示例代码没…...

探讨|使用或不使用机器学习

动动发财的小手&#xff0c;点个赞吧&#xff01; 机器学习擅长解决某些复杂问题&#xff0c;通常涉及特征和结果之间的困难关系&#xff0c;这些关系不能轻易地硬编码为启发式或 if-else 语句。然而&#xff0c;在决定 ML 是否是当前给定问题的良好解决方案时&#xff0c;有一…...

Git笔记--Ubuntu上传本地项目到github

目录 1--基本配置 2--本地上传 1--基本配置 ① 创建ssh-key cd ~/.sshssh-keygen -t rsa -C "邮箱地址"② 查看并关联ssh-key gedit id_rsa.pub 复制内容&#xff0c;在 GitHub 中依次点击 Settings -> SSH and GPG keys -> New SSH key&#xff0c;将 id…...

基于Go编写一个可视化Navicat本地密码解析器

前提 开发小组在测试环境基于docker构建和迁移一个MySQL8.x实例&#xff0c;过程中大意没有记录对应的用户密码&#xff0c;然后发现某开发同事本地Navicat记录了根用户&#xff0c;于是搜索是否能够反解析Navicat中的密码掩码&#xff08;这里可以基本断定Navicat对密码是采用…...

Maven【入门笔记】

Maven 解决版本依赖的问题 https://www.liaoxuefeng.com/wiki/1252599548343744/1309301146648610 如果没有项目管理工具&#xff0c;在开发项目的时候&#xff0c;我们需要手动管理依赖包&#xff0c;需要管理依赖包的版本、去找到并下载依赖包、还有依赖包所依赖的包 等等。…...

Android Studio中使用cmake开发JNI实战

JNI学习大纲 一、JNI编程入门 二、Android Studio中使用cmake开发JNI实战 第一章节我们介绍了JNI的开发步骤&#xff0c;那这一章节我们就开始在Android Studio中实战一下吧&#xff0c;Lets Start。 1. Android Studio中安装CMake插件 AS中菜单栏选择Tools>SDK Manager在…...

第七章 图论

第七章 图论 一、数据结构定义 图的邻接矩阵存储法#define MaxVertexNum 100 // 节点数目的最大值// 无边权&#xff0c;只用0或1表示边是否存在 bool graph[MaxVertexNum][MaxVertexNum];// 有边权 int graph[MaxVertexNum][MaxVertexNum];图的邻接表存储法 把所有节点存储为…...

IEEE SystemVerilog Chapter13 : Tasks and functions (subroutines)

13.2 Overview 任务和函数提供了从描述中的几个不同位置执行通用过程的能力。它们还提供了一种将大型过程分解为小型过程的方法&#xff0c;以便更容易地阅读和调试源代码描述。本小节讨论了任务和函数之间的区别&#xff0c;描述了如何定义和调用任务和函数&#xff0c;并给出…...

day39反转字符串总结

反转字符串原理其实就是交换位置&#xff0c;以中间为分隔点&#xff1b; 基本套路&#xff1a;遍历前一般字符&#xff0c;互换位置&#xff1b; for循环模板 void reverseString(char* s, int sSize){char temp;for (int i 0, j sSize - 1; i < sSize/2; i, j--) {temp…...

使用Socket实现TCP版的回显服务器

文章目录 1. Socket简介2. ServerSocket3. Socket4. 服务器端代码5. 客户端代码 1. Socket简介 Socket&#xff08;Java套接字&#xff09;是Java编程语言提供的一组类和接口&#xff0c;用于实现网络通信。它基于Socket编程接口&#xff0c;提供了一种简单而强大的方式来实现…...

【Nacos篇】Nacos基本操作及配置

官方文档&#xff1a;https://nacos.io/zh-cn/docs/v2/ecology/use-nacos-with-spring-cloud.html 前置条件&#xff1a;SpringCloud脚手架 单机模式下的Nacos控制台&#xff1a; <dependencies><!-- Registry 注册中心相关 --><dependency><groupId>…...

Dockerfile构建Tomcat镜像

准备apache包和jdk并解压 [rootlocalhost tomcat]# ll 总用量 196728 -rw-r--r--. 1 root root 9690027 7月 17 2020 apache-tomcat-8.5.40.tar.gz -rw-r--r--. 1 root root 674 8月 2 20:19 Dockerfile -rw-r--r--. 1 root root 191753373 7月 17 2020 jdk-8u191-…...

k8s的介绍

简介 Kubernetes,简称K8s,是用8代替名字中间的8个字符“ubernete”而成的缩写。是一个开源的,用于管理云平台中多个主机上的容器化的应用, K8s的目标是让部署容器化的应用简单并且高效,K8s提供了应用部署,规划,更新,维护的一种机制。 K8s是Google开源的一个容器编排引…...

mysql sql语句 需要使用like 场景,解决方案

mysql 多重like 解决方案 方案一、使用like 方案二、使用REGEXP 正则匹配 方案三、使用group_concat多重模糊匹配 方案一、使用like 查询user包含小李并且小王的相关数据 SELECT * FROM user WHERE name LIKE %小王% or name like %小王% 方案二、使用REGEXP 正则匹配 查询use…...

通过C语言设计的贪吃蛇游戏(控制台终端)

一、项目介绍 当前通过控制台终端实现一个贪吃蛇小游戏&#xff0c;实现游戏的绘制、更新、控制等功能。 二、实现效果 三、完整代码 下面贴出的代码在Windows系统上编译运行&#xff0c;需要使用conio.h头文件中的getch()函数来获取键盘输入&#xff0c;用于控制蛇的移动。…...

c++实现Qt信号和槽机制

文章目录 简介信号槽信号与槽的连接 特点观察者模式定义观察者模式结构图 实现简单的信号和槽 简介 信号槽机制与Windows下消息机制类似&#xff0c;消息机制是基于回调函数&#xff0c;Qt中用信号与槽来代替函数指针&#xff0c;使程序更安全简洁。  信号和槽机制是 Qt 的核心…...

【Linux】五、进程

一、冯诺依曼体系结构 存储器&#xff1a;指的是内存&#xff1b; 输入设备&#xff1a;键盘、摄像头、话筒&#xff0c;磁盘&#xff0c;网卡&#xff1b; 输出设备&#xff1a;显示器、音响、磁盘、网卡&#xff1b; 中央处理器&#xff08;CPU&#xff09;&#xff1a;运算器…...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)

题目 做法 启动靶机&#xff0c;点进去 点进去 查看URL&#xff0c;有 ?fileflag.php说明存在文件包含&#xff0c;原理是php://filter 协议 当它与包含函数结合时&#xff0c;php://filter流会被当作php文件执行。 用php://filter加编码&#xff0c;能让PHP把文件内容…...

MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用

文章目录 一、背景知识&#xff1a;什么是 B-Tree 和 BTree&#xff1f; B-Tree&#xff08;平衡多路查找树&#xff09; BTree&#xff08;B-Tree 的变种&#xff09; 二、结构对比&#xff1a;一张图看懂 三、为什么 MySQL InnoDB 选择 BTree&#xff1f; 1. 范围查询更快 2…...

Oracle11g安装包

Oracle 11g安装包 适用于windows系统&#xff0c;64位 下载路径 oracle 11g 安装包...