Eureka详解系列(五)--Eureka Server部分的源码和配置
简介
按照原定的计划,我将分三个部分来分析 Eureka 的源码:
- Eureka 的配置体系(已经写完,见Eureka详解系列(三)--探索Eureka强大的配置体系);
- Eureka Client 的交互行为(已经写完,见Eureka详解系列(四)--Eureka Client部分的源码和配置 );
- Eureka Server 的交互行为。
今天,我们来研究第三部分的源码。
分析的思路和第二部分的一样,先明确 Eureka Server 需要具备哪些功能,再从源码层面分析如何实现这些功能,最后补充 Eureka Server 的配置解读。
项目环境
os:win 10
jdk:1.8.0_231
eureka:1.10.11
tomcat:9.0.21
Eureka Server 的功能
还是来回顾 Eureka 的整个交互过程。
首先,Eureka Server 需要和 Eureka Client 交互,所以它需要能够处理 Eureka Client 的各种请求,这些请求包括:
- 获取注册表(Application Client 的请求);
- 注册、续约、注销实例(Application Service 的请求);
除此之外,在集群中,它需要和对等节点交互,交互内容主要包括:
- 将自己的注册表变更操作同步到其他节点;
- 处理其他节点同步注册表的请求。
其实,一个完整的 Eureka Server 项目本身也包含了 Eureka Client 的部分,也就是说,它可以注册自己和消费包括自己在内的服务,可以在 eureka-client.properties 增加以下配置来关闭掉这两个部分的功能(不建议这么做):
# 当前实例是否注册到Eureka Server。默认true
eureka.registration.enabled=false
# 当前实例是否需要从Eureka Server获取服务注册表
eureka.shouldFetchRegistry=false
如何实现这些功能
知道了 Eureka Server 需要具备哪些功能,接下来我们就从源码的角度来看看怎样实现这些功能。
和之前一样,我更多的会从设计的层面来分析,而不会顺序地去看每个过程的代码,即重设计、轻实现。
那么,还是从一个 UML 图开始吧。有了它,相信大家看源码时会更轻松一些。
AbstractInstanceRegistry
里放了一张注册表,用来存放所有的实例对象,通过它可以处理 Eureka Client 或者其他 Eureka Server 的请求,包括注册、续约、注销实例以及获取注册表等。
它的子类PeerAwareInstanceRegistryImpl
提供了多节点的支持,这里以续约实例的方法为例,相同的操作还会被同步到其他节点(对等节点的请求除外)。
public boolean renew(final String appName, final String id, final boolean isReplication) {
// 先调用父类AbstractInstanceRegistry的方法
if (super.renew(appName, id, isReplication)) {
// 再将操作同步到其他节点,最终是调用PeerEurekaNode的方法进行同步
replicateToPeers(Action.Heartbeat, appName, id, null, null, isReplication);
return true;
}
return false;
}
除此之外,PeerAwareInstanceRegistryImpl
还启动了三个定时任务:
- 更新
PeerEurekaNode
列表。例如,当我们使用 DNS 配合 serviceUrl 时,对等节点的地址可能会变化,所以需要及时更新。这个定时任务用于支持集群的故障转移和扩容。 - 更新参数 numberOfRenewsPerMinThreshold--每分钟至少要有多少实例续约。当每分钟续约实例少于这个值时(eureka 认为是灾难性的网络故障导致的),Eureka Server 将进入自我保护模式,此时,它不会再主动淘汰实例,直到我们主动关闭该模式,或者续约实例达到了阈值。我们一般可以通过以下参数来控制。而每分钟至少要有多少实例续约,这个数值受到实例总数的影响,所以需要定时更新。
# 期望实例多久续约一次
eureka.expectedClientRenewalIntervalSeconds=30
# 续约实例的阈值,未达到将开启自我保护模式
eureka.renewalPercentThreshold=0.85
# 是否启用保护模式
eureka.enableSelfPreservation=true
- 丢弃未能及时续约的实例。默认情况下,实例超过 90s 未能续约的话,Eureka Server 会将其丢弃掉。
从哪里开始看源码
Eureka Server 是作为一个 Web 应用运行的,要看源码比较难找到入口。打开Eureka详解系列(二)--如何使用Eureka(原生API,无Spring) 例子里的 web.xml,可以看到配置了一个监听器,这个类就是 Eureka Server 初始化的入口。
<listener>
<listener-class>com.netflix.eureka.EurekaBootStrap</listener-class>
</listener>
在这个类里面,我们主要关注这一段代码(代码有删减)。
protected void initEurekaServerContext() throws Exception {
// 下面这一段是为了初始化Eureka Client所需要的对象,上一篇博客讲过了
EurekaInstanceConfig instanceConfig = new MyDataCenterInstanceConfig();
ApplicationInfoManager applicationInfoManager = new ApplicationInfoManager(
instanceConfig, new EurekaConfigBasedInstanceInfoProvider(instanceConfig).get());
EurekaClientConfig eurekaClientConfig = new DefaultEurekaClientConfig();
eurekaClient = new DiscoveryClient(applicationInfoManager, eurekaClientConfig);
// 加载eureka-server.properties的配置
EurekaServerConfig eurekaServerConfig = new DefaultEurekaServerConfig();
ServerCodecs serverCodecs = new DefaultServerCodecs(eurekaServerConfig);
// 初始化注册表对象(支持多节点)
PeerAwareInstanceRegistry registry = new PeerAwareInstanceRegistryImpl(
eurekaServerConfig,
eurekaClient.getEurekaClientConfig(),
serverCodecs,
eurekaClient
);
// 初始化PeerEurekaNodes对象
PeerEurekaNodes peerEurekaNodes = getPeerEurekaNodes(
registry,
eurekaServerConfig,
eurekaClient.getEurekaClientConfig(),
serverCodecs,
applicationInfoManager
);
// 1. 初始化PeerEurekaNode列表,
// 2. 启动定时任务:更新PeerEurekaNode列表
peerEurekaNodes.start();
// 1. 将PeerEurekaNode列表的指针给到PeerEurekaNodes对象对象
// 2. 启动定时任务:更新参数numberOfRenewsPerMinThreshold--每分钟至少要有多少实例续约,它是判断是否开启自我保护模式的依据
registry.init(peerEurekaNodes);
// 从其他节点获取实例列表并注册到本地的注册表
int registryCount = registry.syncUp();
// 1. 初始化参数numberOfRenewsPerMinThreshold--每分钟要求多少实例续约
// 2. 开启定时任务:淘汰未能正常续约的实例
registry.openForTraffic(applicationInfoManager, registryCount);
}
完成初始化后,Eureka Server 就可以处理 Eureka Client 的请求了。因为 Eureka Server 使用 jersey 作 Web 框架(jersey 和 struts2、springMVC 作用差不多,没接触过也不碍事),所以,只要找到添加了javax.ws.rs.Path
注解的类,就能找到这部分代码的入口。
Eureka Server 的配置解读
回顾下Eureka详解系列(三)--探索Eureka强大的配置体系的内容,在 Eureka 里,配置分成了三种:
- EurekaInstanceConfig:当前实例身份的配置信息,即我是谁?
- EurekaServerConfig:一些影响当前Eureka Server和客户端或对等节点交互行为的配置信息,即怎么交互?
- EurekaClientConfig:一些影响当前实例和Eureka Server交互行为的配置信息,即和谁交互?怎么交互?
这里我们来讲讲EurekaServerConfig
的配置参数,对应的是 eureka-server.properties 里的配置。
# 期望实例多久续约一次
eureka.expectedClientRenewalIntervalSeconds=30
# 续约实例的阈值,未达到将开启自我保护模式
eureka.renewalPercentThreshold=0.85
# 是否启用保护模式
eureka.enableSelfPreservation=true
# 更新参数numberOfRenewsPerMinThreshold的定时任务多久执行一次
renewalThresholdUpdateIntervalM=900000
# 更新PeerEurekaNode列表的定时任务多久执行一次
peerEurekaNodesUpdateIntervalMs=600000
# 淘汰未能正常续约实例的定时任务多久执行一次
evictionIntervalTimerInMs=60000
# 这几个一般不用,我就不展开了。有需要的话可以
#awsAccessId=
#awsSecretKey=
eipBindRebindRetries=3
eipBindRebindRetryIntervalMsWhenUnbound=60000
eipBindRebindRetryIntervalMs=300000
waitTimeInMsWhenSyncEmpty=300000
shouldBatchReplication=false
disableDelta=false
numberRegistrySyncRetries=5
registrySyncRetryWaitMs=30000
enableReplicatedRequestCompression=false
minAvailableInstancesForPeerReplication=-1
peerEurekaStatusRefreshTimeIntervalMs=30000
peerNodeConnectTimeoutMs=1000
peerNodeReadTimeoutMs=5000
peerNodeTotalConnections=1000
peerNodeTotalConnectionsPerHost=500
numberOfReplicationRetries=5
maxElementsInPeerReplicationPool=10000
maxIdleThreadAgeInMinutesForPeerReplication=15
minThreadsForPeerReplication=5
maxThreadsForPeerReplication=20
maxTimeForReplication=30000
primeAwsReplicaConnections=true
maxIdleThreadAgeInMinutesForStatusReplication=10
minThreadsForStatusReplication=1
maxThreadsForStatusReplication=1
maxElementsInStatusReplicationPool=10000
disableDeltaForRemoteRegions=false
remoteRegionConnectTimeoutMs=2000
remoteRegionReadTimeoutMs=5000
remoteRegionTotalConnections=1000
remoteRegionTotalConnectionsPerHost=500
remoteRegionConnectionIdleTimeoutSeconds=30
remoteRegion.gzipContent=true
#remoteRegionUrlsWithName=
#remoteRegion.appWhiteList=
remoteRegion.registryFetchIntervalInSeconds=30
remoteRegion.fetchThreadPoolSize=20
#remoteRegion.trustStoreFileName=
remoteRegion.trustStorePassword=changeit
remoteRegion.disable.transparent.fallback=false
shouldUseAwsAsgApi=true
asgQueryTimeoutMs=300
asgUpdateIntervalMs=300000
asgCacheExpiryTimeoutMs=600000
retentionTimeInMSInDeltaQueue=180000
deltaRetentionTimerIntervalInMs=30000
responseCacheAutoExpirationInSeconds=180
responseCacheUpdateIntervalMs=30000
shouldUseReadOnlyResponseCache=true
syncWhenTimestampDiffers=true
auth.shouldLogIdentityHeaders=true
route53BindRebindRetries=3
route53BindRebindRetryIntervalMs=300000
route53DomainTTL=30
initialCapacityOfResponseCache=1000
jsonCodecName=com.netflix.discovery.converters.wrappers.CodecWrappers.LegacyJacksonJson
xmlCodecName=com.netflix.discovery.converters.wrappers.CodecWrappers.XStreamXml
以上比较宏观地讲完了 Eureka Server 的源码和配置,具体的细节欢迎私信交流。
最后,感谢您的阅读。
参考资料
https://github.com/Netflix/eureka/wiki/Eureka-at-a-glance
本文为原创文章,转载请附上原文出处链接:https://www.cnblogs.com/ZhangZiSheng001/p/14395079.html
Eureka详解系列(五)--Eureka Server部分的源码和配置的更多相关文章
- Eureka详解系列(四)--Eureka Client部分的源码和配置
简介 按照原定的计划,我将分三个部分来分析 Eureka 的源码: Eureka 的配置体系(已经写完,见Eureka详解系列(三)--探索Eureka强大的配置体系): Eureka Client ...
- Eureka详解系列(二)--如何使用Eureka(原生API,无Spring)
简介 通过上一篇博客 Eureka详解系列(一)--先谈谈负载均衡器 ,我们知道了 Eureka 是什么以及为什么要使用它,今天,我们开始研究如何使用 Eureka. 在此之前,先说明一点.网上几乎所 ...
- 详解Mybatis拦截器(从使用到源码)
详解Mybatis拦截器(从使用到源码) MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能. 本文从配置到源码进行分析. 一.拦截器介绍 MyBatis 允许你在 ...
- Scala 深入浅出实战经典 第61讲:Scala中隐式参数与隐式转换的联合使用实战详解及其在Spark中的应用源码解析
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载: 百度云盘:http://pan.baidu.com/s/1c0noOt ...
- Scala 深入浅出实战经典 第60讲:Scala中隐式参数实战详解以及在Spark中的应用源码解析
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- Mybatis详解系列(五)--Mybatis Generator和全注解风格的MyBatis3DynamicSql
简介 Mybatis Generator (MBG) 是 Mybatis 官方提供的代码生成器,通过它可以在项目中自动生成简单的 CRUD 方法,甚至"无所不能"的高级条件查询(M ...
- Eureka详解系列(一)--先谈谈负载均衡器
这个系列开始研究 Eureka,在此之前,先来谈谈负载均衡器. 本质上,Eureka 就是一个负载均衡器,可能有的人会说,它是一个服务注册中心,用来注册服务的,这种说法不能说错,只是有点片面. 在这篇 ...
- Eureka详解系列(三)--探索Eureka强大的配置体系
简介 通过前面的两篇博客,我们知道了:什么是 Eureka?为什么使用 Eureka?如何适用 Eureka?今天,我们开始来研究 Eureka 的源码,先从配置部分的源码开始看,其他部分后面再补充. ...
- 源码详解系列(五) ------ C3P0的使用和分析(包括JNDI)
简介 c3p0是用于创建和管理连接,利用"池"的方式复用连接减少资源开销,和其他数据源一样,也具有连接数控制.连接可靠性测试.连接泄露控制.缓存语句等功能.目前,hibernate ...
随机推荐
- 分布式系统:xxl-job改造spring-cloud
目录 改造原因 主要改造思路 调度中心 调度中心 执行器侧 总结 修改后的源码仓库地址:GitHub. : 改造原因 原有的xxl-job使用自己实现的http协议进行注册以及调度等,与目前框架中本身 ...
- [Usaco 2012 Feb]Nearby Cows
题目描述 FJ发现他的牛经常跑到附近的草地去吃草,FJ准备给每个草地种足够的草供这个草地以及附近草地的奶牛来吃.FJ有N个草地(1<=N<=100000),有N-1条双向道路连接这些草地, ...
- 1.2V升3.3V芯片,大电流,应用MCU供电,3.3V稳压源
MCU供电一般是2.5V-5V之间等等都有,1.2V需要升到3.3V的升压芯片来稳压输出3.3V给MCU供电. 同时1.2V的输入电压低,说明供电端的能量也是属于低能量的,对于芯片自身供货是也要求高. ...
- Python 中 lru_cache 的使用和实现
在计算机软件领域,缓存(Cache)指的是将部分数据存储在内存中,以便下次能够更快地访问这些数据,这也是一个典型的用空间换时间的例子.一般用于缓存的内存空间是固定的,当有更多的数据需要缓存的时候,需要 ...
- 【2020CSP-S模拟赛day5】总结
爆零自闭赛 写在前面 于2022.11.1 这一次题目质量很高(以至于什么都不会) 再一度体验了省选Orz.比赛大体情况,刨去std, wzc神仙230分,比剩下的加起来都高.zyz神仙60分. 其余 ...
- Samba共享工具安装
Samba 是一种在局域网上共享文件的一种通信协议,它为局域网内的不同计算机之间提供文件的共享服务. (1)下载并安装 Samba 工具. 确定 Ubuntu 已连接到互联网, 执行如下命令下载 Sa ...
- ROS教程(一):ROS安装教程(详细图文)
ros教程:ros安装 目录 前言 一.版本选择 二.开始安装 2.1 软件中心配置 2.2 添加源 2.3 安装 三.验证ROS 前言 关于ROS(Robot OS 机器人操作系统),估计看这个教程 ...
- jackson学习之二:jackson-core
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- mybatis缓存源码分析之浅谈缓存设计
本文是关于mybatis缓存模块设计的读后感,关于缓存的思考,关于mybatis的缓存源码详细分析在另一篇文章:https://www.cnblogs.com/gmt-hao/p/12448896.h ...
- Servlet中的一些注意事项
servlet中的一些注意事项 1 什么是servlet? 1)Servlet是Sun公司制定的一套技术标准,包含与Web应用相关的一系列接口,是Web应用实现方式的宏观解决方案.而具体的Servle ...