Eureka源码系列 —— 10.服务同步
前言
eureka客户端和服务端的通信前面九篇文章都已经将源码分析完毕,这篇文章我们将重点放在eureka-server集群内的多个节点间是如何通信的。
正文
eureka-server集群采用peer to peer的通信方式,简称p2p。即没有主副节点,所有节点地位平等。这就意味着所有节点要将自己的信息传递到自己节点中,达到信息的最终一致性,注意eureka采用的是CAP中的AP模型。
源码中关键的是eureka-server启动时EurekaBootStrap#initEurekaServerContext
方法中的这两步:
维护节点信息
维护节点信息的方法会启动一个定时任务,每10min执行一次,这个定时任务的逻辑:
这个方法中会根据集群内节点的配置,来同步节点上下线的信息。维护集群内节点的信息正确。
同步注册表
同步注册表依赖于eureka-server的设计,在eureka-server的设计中,server本身也是一个client,会在server启动的时候拉取其他server端的全量注册表。当拉取到注册表之后,将注册表中的所有应用的实例全部在本server注册一遍。
如果没有拉取到的话,隔30s再拉取一遍,共计拉取5次。
同步实例状态
当eureka-client向某个server发起注册或者下线等等重要的通信动作时,接受到请求的server不但会完成自己的处理请求逻辑,还会调用com.netflix.eureka.registry.PeerAwareInstanceRegistryImpl#replicateToPeers
方法将client信息同步到集群内其他节点,比如处理服务注册的方法中:
我们来看replicateToPeers
方法实现:
- 首先从参数
isReplication
判断动作的来源是否已经是 其他server节点同步来的,如果是的话,就不再向其他节点传播了 - 如果不是,则遍历server集群内的其他节点,向他们同步实例信息
继续看replicateInstanceActionsToPeers
方法:
方法内列出了所有会在集群内节点同步的通信动作:
- 注册
- 心跳
- 线下
- StatusUpdate
- DeleteStatusOverride
而向其他节点发起同步的时候,其实就是发起了一个远程调用,不过值得注意的是,远程调用的参数里面携带了isReplication=true
这个参数,表明这个同步是由其他节点同步来的。不然就会引起节点间无限同步的死循环。
批处理
eureka-server在同步实例状态的时候,为了性能考虑,减少网络开销,设计了批处理的优化手段。可以看这篇博文https://www.iocoder.cn/Eureka/batch-tasks/
总结
eureka-server集群采用p2p的通信设计。
server启动的时候会感知到集群内的其他节点,并从其他节点复制已有的注册表到自己本地,完成本地服务实例的注册。
client与单个节点通信,完成诸如注册、下线等请求,然后这个server节点负责将client的动作复制给集群内的其他节点。