Eureka 学习 源码分析11 集群同步
- Eureka-Server 集群不区分主从节点或者 Primary & Secondary 节点,所有节点相同角色( 也就是没有角色 ),完全对等。
- Eureka-Client 可以向任意 Eureka-Client 发起任意读写操作,Eureka-Server 将操作复制到另外的 Eureka-Server 以达到最终一致性。注意,Eureka-Server 是选择了 AP 的组件。
Eureka-Server 在初始化时,调用 EurekaBootStrap#getPeerEurekaNodes(...)
方法,创建 PeerEurekaNodes
2.1 集群节点启动
调用 PeerEurekaNodes#start()
方法,集群节点启动,主要完成两个逻辑:
- 初始化集群节点信息
- 初始化固定周期( 默认:10 分钟,可配置 )更新集群节点信息的任务
2.2 更新集群节点信息
调用 #resolvePeerUrls()
方法,获得 Eureka-Server 集群服务地址数组
获得 Eureka-Server 集群服务地址数组。
移除自身节点,避免向自己同步。
调用 #updatePeerEurekaNodes()
方法,更新集群节点信息,主要完成两部分逻辑:
- 添加新增的集群节点
- 关闭删除的集群节点
3. 获取初始注册信息
Eureka-Server 启动时,调用 PeerAwareInstanceRegistryImpl#syncUp()
方法,从集群的一个 Eureka-Server 节点获取初始注册信息
若调用 #syncUp()
方法,未获取到应用实例,则 Eureka-Server 会有一段时间( 默认:5 分钟,可配 )不允许被 Eureka-Client 获取注册信息,避免影响 Eureka-Client 。
(1) Eureka-Server 发起同步操作
(2) 另一个Eureka-Server接收同步操作
(3) 处理Eureka-Server 同步结果
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4.2 发起 Eureka-Server 同步操作
Eureka-Server 在完成 Eureka-Client 发起的上述操作在自身节点的执行后,向集群内其他 Eureka-Server 发起同步操作
最后一行,调用 #replicateToPeers(...)
方法,传递对应的同步操作类型,发起同步操作
-
Cancel :调用
PeerEurekaNode#cancel(...)
方法,点击 链接 查看实现。 -
Heartbeat :调用
PeerEurekaNode#heartbeat(...)
方法,点击 链接 查看实现。 -
Register :调用
PeerEurekaNode#register(...)
方法,点击 链接 查看实现。 -
StatusUpdate :调用
PeerEurekaNode#statusUpdate(...)
方法,点击 链接 查看实现。 -
DeleteStatusOverride :调用
PeerEurekaNode#deleteStatusOverride(...)
方法,点击 链接 查看实现。
相同应用实例的相同同步操作使用相同任务编号
我们看到” 接收线程( Runner )合并任务,将相同任务编号的任务合并,只执行一次。 “,因此,相同应用实例的相同同步操作就能被合并,减少操作量
ReplicationTaskProcessor#process(task)
,处理单任务,用于 Eureka-Server 向亚马逊 AWS 的 ASG ( Autoscaling Group
) 同步状态
ReplicationTaskProcessor#process(tasks)
,处理批量任务,用于 Eureka-Server 集群注册信息的同步操作任务,通过调用被同步的 Eureka-Server 的 peerreplication/batch/
接口,一次性将批量( 多个 )的同步操作任务发起请求
4.3 接收 Eureka-Server 同步操作
com.netflix.eureka.resources.PeerReplicationResource
,同步操作任务 Resource
同步信息分成:
(1)注册Register
(2) 心跳Heartbeat
(3) 取消Cancel
(4) 状态更新StatusUpdate
(5) 删除状态覆盖 DeleteStatusOverride
4.4 处理 Eureka-Server 同步结果
接 ReplicationTaskProcessor#process(tasks)
方法,处理批量提交同步操作任务的响应
该情况为永久错误,会重试该同步操作任务
非预期异常,目前 Eureka-Server 在代码上看下来,不会抛出这样的异常。该情况为永久错误,会重试该同步操作任务
但是光靠注册请求判断 lastDirtyTimestamp
显然是不够的,因为网络异常情况下时,同步操作任务多次执行失败到达过期时间后,此时在 Eureka-Server 集群同步起到最终一致性最最最关键性出现了:Heartbeat 。因为 Heartbeat 会周期性的执行,通过它一方面可以判断 Eureka-Server 是否存在心跳对应的应用实例,另外一方面可以比较应用实例的 lastDirtyTimestamp
当满足下面任意条件,Eureka-Server 返回 404 状态码:
- 1)Eureka-Server 应用实例不存在,点击 链接 查看触发条件代码位置。
- 2)Eureka-Server 应用实例状态为
UNKNOWN
-
3)请求的
lastDirtyTimestamp
更大
请求方接收到 404 状态码返回后,认为 Eureka-Server 应用实例实际是不存在的,重新发起应用实例的注册