摘要:在本篇文章中主要对Eureka的Renew(服务续约),从服务提供者发起续约请求开始分析,通过阅读源码和画时序图的方式,展示Eureka服务续约的整个生命周期。服务续约主要是把服务续约的信息更新到自身的Eureka Server中,然后再同步到其它Eureka Server中。
Renew(服务续约)
概述
Renew(服务续约)操作由Service Provider定期调用,类似于heartbeat。目的是隔一段时间Service Provider调用接口,告诉Eureka Server它还活着没挂,不要把它T了。通俗的说就是它们两之间的心跳检测,避免服务提供者被剔除掉。
请参考:Spring Cloud Eureka名词解释
服务续约配置
Renew操作会在Service Provider定时发起,用来通知Eureka Server自己还活着。 这里有两个比较重要的配置需要如下,可以在Run之前配置。
Renew频率。默认是30秒
,也就是每30秒会向Eureka Server发起Renew操作。
服务失效时间。默认是90秒
,也就是如果Eureka Server在90秒内没有接收到来自Service Provider的Renew操作,就会把Service Provider剔除
。
Renew源码分析
服务提供者实现细节
服务提供者发发起服务续约的时序图,如下图所示,大家先直观的看一下时序图,等阅读完源码再回顾一下。
- 在com.netflix.discovery.DiscoveryClient.initScheduledTasks()中的1272行,TimedSupervisorTask会定时发起服务续约,代码如下所示:123456789101112// Heartbeat timerscheduler.schedule(new TimedSupervisorTask("heartbeat",scheduler,heartbeatExecutor,renewalIntervalInSecs,TimeUnit.SECONDS,expBackOffBound,new HeartbeatThread()),renewalIntervalInSecs, TimeUnit.SECONDS);
2.在com.netflix.discovery.DiscoveryClient中的1393行,有一个HeartbeatThread
线程发起续约操作
renew()调用eureka-client-1.4.11.jarcom.netflix.discovery.DiscoveryClient中829
行renew()发起PUT Reset
请求,调用com.netflix.eureka.resources.InstanceResource中的renewLease()续约。
Netflix中的Eureka Core实现细节
NetFlix中Eureka Core中的服务续约时序图,如下图所示。
打开
com.netflix.eureka.resources.InstanceResource
中的106
行的renewLease()
方法,代码如下:123456789101112private final PeerAwareInstanceRegistry registrypublic Response renewLease(@HeaderParam(PeerEurekaNode.HEADER_REPLICATION) String isReplication,@QueryParam("overriddenstatus") String overriddenStatus,@QueryParam("status") String status,@QueryParam("lastDirtyTimestamp") String lastDirtyTimestamp) {boolean isFromReplicaNode = "true".equals(isReplication);//调用boolean isSuccess = registry.renew(app.getName(), id, isFromReplicaNode);//其余省略}点开registry.renew(app.getName(), id, isFromReplicaNode);我们可以看到,调用了
org.springframework.cloud.netflix.eureka.server.InstanceRegistry
中的renew()
方法,代码如下:1234567891011121314151617181920212223public boolean renew(final String appName, final String serverId,boolean isReplication) {log("renew " + appName + " serverId " + serverId + ", isReplication {}"+ isReplication);List<Application> applications = getSortedApplications();for (Application input : applications) {if (input.getName().equals(appName)) {InstanceInfo instance = null;for (InstanceInfo info : input.getInstances()) {if (info.getHostName().equals(serverId)) {instance = info;break;}}publishEvent(new EurekaInstanceRenewedEvent(this, appName, serverId,instance, isReplication));break;}}//调用com.netflix.eureka.registry.PeerAwareInstanceRegistryImpl中的renew方法return super.renew(appName, serverId, isReplication);}
3.从super.renew()
看到调用了父类中的com.netflix.eureka.registry.PeerAwareInstanceRegistryImpl
中420
行的renew()
方法,代码如下:
3.1 从上面代码中super.renew(appName, id, isReplication)
可以看出调用的是com.netflix.eureka.registry.AbstractInstanceRegistry中345
行的renew()方法,代码如下所示
其中 leaseToRenew.renew()
是调用com.netflix.eureka.lease.Lease62
行的renew()方法
3.2 replicateToPeers(Action.Heartbeat, appName, id, null, null, isReplication);调用自身的replicateToPeers()
方法,在com.netflix.eureka.registry.PeerAwareInstanceRegistryImpl中的618
行,主要接口实现方式和register基本一致:首先更新自身Eureka Server中服务的状态,再同步到其它Eureka Server中。
至此,Eureka服务续约源码分析结束,大家有兴趣可自行阅读。
源码分析链接
其它源码分析链接:
Spring Cloud中@EnableEurekaClient源码分析:
http://blog.xujin.org/sc/sc-enableEurekaClient-annonation/
Spring Cloud Eureka服务注册源码分析:
http://blog.xujin.org/sc/sc-eureka-register/