状态说明
STARTING : 表示服务正在启动中
DOWN: 表示服务已经宕机,无法继续提供服务
UP : 服务正常运行
OUT_OF_SERVICE : 不再提供服务,其他的Eureka Client将调用不到该服务,一般有人为的调用接口设置的,如:强制下线。
UNKNOWN: 未知状态
状态变更
容器启动
在容器刚刚启动,实例化instance信息的时候,默认状态为STARTING
value = ApplicationInfoManager.class, search = SearchStrategy.CURRENT) (springframework.cloud.context.config.annotation.RefreshScope . public ApplicationInfoManager eurekaApplicationInfoManager(EurekaInstanceConfig config) { InstanceInfo instanceInfo = new InstanceInfoFactory().create(config); return new ApplicationInfoManager(config, instanceInfo); }
初始化ApplicationInfoManager的时候,会设置一个最初的Instance信息,这个时候的instance信息的状态为STARTING
public InstanceInfo create(EurekaInstanceConfig config) { LeaseInfo.Builder leaseInfoBuilder = LeaseInfo.Builder.newBuilder() .setRenewalIntervalInSecs(config.getLeaseRenewalIntervalInSeconds()) .setDurationInSecs(config.getLeaseExpirationDurationInSeconds()); InstanceInfo.Builder builder = InstanceInfo.Builder.newBuilder(); // ..... 省略N多代码 // config.isInstanceEnabledOnit() 默认为false if (!config.isInstanceEnabledOnit()) { // 设置实例的状态为STARTING InstanceInfo.InstanceStatus initialStatus = InstanceInfo.InstanceStatus.STARTING; if (log.isInfoEnabled()) { log.info("Setting initial instance status as: " + initialStatus); } builder.setStatus(initialStatus); } // ..... 省略N多代码 InstanceInfo instanceInfo = builder.build(); instanceInfo.setLeaseInfo(leaseInfoBuilder.build()); return instanceInfo; }
上面的代码是做了一些初始化的信息,设置Instance的状态为STARTING,接下来,在自动注册类初始化的时候,
会设置Instance的状态为UP,同时触发监听器,让Eureka Client发起注册。
AutoServiceRegistrationProperties.class) (value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true) (public EurekaAutoServiceRegistration eurekaAutoServiceRegistration(ApplicationContext context, EurekaServiceRegistry registry, EurekaRegistration registration) { return new EurekaAutoServiceRegistration(context, registry, registration); }
流程图如下:
1528437997(1).jpg
关于容器启动时注册的具体细节,可以细看https://blog.csdn.net/u012394095/article/details/80693713中自动注册那一小结
健康检查器
在Eureka Client端,有一个40秒执行一次的定时任务,会定时的去扫描自身的信息,查看自身信息是否发生改变,
其中就有一个对状态的检测,这个时候,如果设置了健康检查器,那么会以健康检查的结果为准,判断当前实例的
状态
// DiscoverClient.java void refreshInstanceInfo() { // 1. 判断数据中心的数据是否发生改变, applicationInfoManager.refreshDataCenterInfoIfRequired(); // 2.判断配置是否发生改变 applicationInfoManager.refreshLeaseInfoIfRequired(); InstanceStatus status; try { // 通过健康检查器,获取应用的最新状态 status = getHealthCheckHandler().getStatus(instanceInfo.getStatus()); } catch (Exception e) { logger.warn("Exception from healthcheckHandler.getStatus, setting status to DOWN", e); status = InstanceStatus.DOWN; } if (null != status) { // 设置状态 applicationInfoManager.setInstanceStatus(status); } }
健康检查器,获取状态。
public InstanceInfo.InstanceStatus getStatus(InstanceInfo.InstanceStatus currentStatus) { // 判断instance的状态。 if (null == callback || InstanceInfo.InstanceStatus.STARTING == currentStatus || InstanceInfo.InstanceStatus.OUT_OF_SERVICE == currentStatus) { // Do not go to healthcheck handler if the status is starting or OOS. return currentStatus; } return callback.isHealthy() ? InstanceInfo.InstanceStatus.UP : InstanceInfo.InstanceStatus.DOWN; }
代码如上,如果callback对象不为空的话,那么会调用callback的isHealthy()方法判断实例的状态。
同时会将获取到的状态调用 applicationInfoManager.setInstanceStatus(status) , 只有当传入的
状态和他本身的状态不一致时,才会更新, 如果更新了状态,那么同时也会想服务器注册最新的信息
具体可以看 :https://blog.csdn.net/u012394095/article/details/80966441
强制下线
容器销毁
在使用kill pid 这种方式去终止进程的时候,spring容器会销毁,在销毁的时候会触发一些shutDown这种方法。
EurekaAutoServiceRegistration是一个实现了SmartLifecycle的接口类,在spring容器销毁的时候,会调用其
stop方法。
public void stop() { this.serviceRegistry.deregister(this.registration); this.running.set(false); }
调用了deregister方法,
public void deregister(EurekaRegistration reg) { if (reg.getApplicationInfoManager().getInfo() != null) { if (log.isInfoEnabled()) { log.info("Unregistering application " + reg.getInstanceConfig().getAppname() + " with eureka with status DOWN"); } // 设置实例的状态为DOWN reg.getApplicationInfoManager().setInstanceStatus(InstanceInfo.InstanceStatus.DOWN); //触发DiscoverClient的shutdown方法 reg.getEurekaClient().shutdown(); } }
reg.getApplicationInfoManager().setInstanceStatus(InstanceInfo.InstanceStatus.DOWN);
这行代码,设置了实例的状态为DOWN,这个时候会触发状态监听器,将实例的最新状态重新注册到Eureka上面去
,这个时候在Eureka上面的状态,该类的状态就是DOWN,通过日志可以很详细的看出来
Eureka Client
2018-06-08 15:14:46.944 [Thread-12] INFO o.s.c.n.e.serviceregistry.EurekaServiceRegistry - Unregistering application gs-job-admin with eureka with status DOWN 2018-06-08 15:14:46.944 [Thread-12] WARN com.netflix.discovery.DiscoveryClient - Saw local status change event StatusChangeEvent [timestamp=1528442086944, current=DOWN, previous=UP] 2018-06-08 15:14:46.945 [DiscoveryClient-InstanceInfoReplicator-0] INFO com.netflix.discovery.DiscoveryClient - DiscoveryClient_GS-JOB-ADMIN/10.28.144.127:8200: registering service... 2018-06-08 15:14:46.946 [Thread-12] INFO com.netflix.discovery.DiscoveryClient - Shutting down DiscoveryClient ... 2018-06-08 15:14:46.948 [DiscoveryClient-InstanceInfoReplicator-0] INFO com.netflix.discovery.DiscoveryClient - DiscoveryClient_GS-JOB-ADMIN/10.28.144.127:8200 - registration status: 204 2018-06-08 15:14:46.948 [Thread-12] INFO com.netflix.discovery.DiscoveryClient - Unregistering ... 2018-06-08 15:14:46.953 [Thread-12] INFO com.netflix.discovery.DiscoveryClient - DiscoveryClient_GS-JOB-ADMIN/10.28.144.127:8200 - deregister status: 200 2018-06-08 15:14:46.955 [Thread-12] INFO com.netflix.discovery.DiscoveryClient - Completed shut down of DiscoveryClient
Eureka Server
2018-06-08 15:14:47.455 eureka-resitry-ms 10.29.184.48 [http-nio-8081-exec-3] INFO c.e.p.b.e.r.listener.InstanceStateChangeListener.listen:108 - instance registered GS-JOB-ADMIN 10.28.144.127:8200 true DOWN, {management.port=18200} 2018-06-08 15:14:47.456 eureka-resitry-ms 10.29.184.48 [http-nio-8081-exec-3] INFO c.netflix.eureka.registry.AbstractInstanceRegistry.register:267 - Registered instance GS-JOB-ADMIN/10.28.144.127:8200 with status DOWN (replication=true) 2018-06-08 15:14:47.457 eureka-resitry-ms 10.29.184.48 [http-nio-8081-exec-3] INFO c.netflix.eureka.registry.AbstractInstanceRegistry.internalCancel:331 - Cancelled instance GS-JOB-ADMIN/10.28.144.127:8200 (replication=true)
状态变更为DOWN 之后, Eureka Client会继续执行unregister()方法,执行下线操作。