【2020-02-23】对Eureka的一些理解

前言

    从这周的周一开始,完成居家隔离的人员便可以回公司上班,于是新一年度开会、开发、扯淡的职业生涯又展开在了我的面前。没有一点点防备,也没有一丝顾虑,你就这样出现。对于工作、学习的心态调整好了,这一周轻松了很多,虽然还是有点忙,还是一堆事。

    这周学习上,对于SpringCloud组件恶补了一番,主要看了Eureka的源码,对Feign的调用过程进行了涉猎。下面主要讲讲对Eureka的理解。

一、EurekaServer

    服务端的核心类是  PeerAwareInstanceRegistryImpl,它的成员变量peerEurekaNodes存放的就是所有服务节点。在初始化EurekaServerAutoConfiguration时会将EurekaServerInitializerConfiguration注入Spring容器,而它实现了SmartLifecycle接口,也就是在Spring初始化结束后会调它的start方法。在start方法中:

调用了 EurekaServerBootstrap#contextInitialized 方法,该方法调用InstanceRegistry#openForTraffic,最终调用了 evictionTimer.schedule(EvictionTask  ) ,其中timer是一个以守护线程运行的定时器,每隔60秒执行一次EvictionTask的run方法,对过期的实例剔除。

二、EurekaClient

    客户端的核心类是DiscoveryClient,在它的构造器中通过initScheduledTasks方法对客户端的定时器进行了初始化,包括:

CacheRefreshThread:每30秒去server同步最新服务列表信息;

HeartbeatThread:每30秒去server续约;

InstanceInfoReplicator:每30秒将InstanceInfo的信息往server同步,每当有instanceStatus改变的时候也会触发同步。

三、服务注册的过程

    客户端启动后,如果 clientConfig.shouldEnforceRegistrationAtInit() 返回的是true并且 clientConfig.shouldRegisterWithEureka()返回的是true,才会立即往服务端注册,否则需第一次心跳触发的时候才会往服务端注册。调用register时最终通过http调用调到了一台服务器的ApplicationResource#addInstance方法,将服务注册上去,注册之后再同步给其他EurekaServer信息。

1 public void register(final InstanceInfo info, final boolean isReplication) {
2         int leaseDuration = Lease.DEFAULT_DURATION_IN_SECS;
3         if (info.getLeaseInfo() != null && info.getLeaseInfo().getDurationInSecs() > 0) {
4             leaseDuration = info.getLeaseInfo().getDurationInSecs();
5         }
6         super.register(info, leaseDuration, isReplication);//注册服务
7         replicateToPeers(Action.Register, info.getAppName(), info.getId(), info, null, isReplication);//将新加的服务同步给其他EurekaServer
8     }

后记

    发现EurekaServer中也有Client的依赖,而且每次Server初始化也会初始化Client,故可以这样理解:一个Server可以看成具有Server+Client双重身份,它也会每隔30秒往其他Server同步服务信息,更新本地的列表。

 

posted on 2020-02-23 23:35  淡墨痕  阅读(278)  评论(0编辑  收藏  举报