// DiscoveryClient构造器中: if (clientConfig.shouldRegisterWithEureka() && clientConfig.shouldEnforceRegistrationAtInit()) { //配置了开启注册和强制注册初始化时,则会立马调用注册方法 try { if (!register() ) { throw new IllegalStateException("Registration error at startup. Invalid server response."); } } catch (Throwable th) { logger.error("Registration error at startup: {}", th.getMessage()); throw new IllegalStateException(th); } } ----------------------------------- // 实例信息复制器初始化,并且启动。 instanceInfoReplicator = new InstanceInfoReplicator( this, instanceInfo, clientConfig.getInstanceInfoReplicationIntervalSeconds(), 2); // burstSize instanceInfoReplicator.start(clientConfig.getInitialInstanceInfoReplicationIntervalSeconds()); // InstanceInfoReplicator.java实现了RUNNABLE,接着看start方法 public void start(int initialDelayMs) { if (started.compareAndSet(false, true)) { instanceInfo.setIsDirty(); // for initial register // 30秒后执行当前对象任务 Future next = scheduler.schedule(this, initialDelayMs, TimeUnit.SECONDS); scheduledPeriodicRef.set(next); } } public void run() { try { // 刷新实例信息 discoveryClient.refreshInstanceInfo(); // 判断实例信息是否发生改变 // isInstanceInfoDirty默认为false,实例信息发生改变时会被设为true // 被设为ture,则dirtyTimestamp不为null,则发起注册请求 Long dirtyTimestamp = instanceInfo.isDirtyWithTime(); if (dirtyTimestamp != null) { // 注册 discoveryClient.register(); instanceInfo.unsetIsDirty(dirtyTimestamp); } } catch (Throwable t) { logger.warn("There was a problem with the instance info replicator", t); } finally { // 40秒后执行 Future next = scheduler.schedule(this, replicationIntervalSeconds, TimeUnit.SECONDS); scheduledPeriodicRef.set(next); } } ------------------------------------ /** * 通过REST调用注册eureka服务 */ boolean register() throws Throwable { logger.info(PREFIX + "{}: registering service...", appPathIdentifier); EurekaHttpResponse<Void> httpResponse; try { httpResponse = eurekaTransport.registrationClient.register(instanceInfo); } catch (Exception e) { logger.warn(PREFIX + "{} - registration failed {}", appPathIdentifier, e.getMessage(), e); throw e; } if (logger.isInfoEnabled()) { logger.info(PREFIX + "{} - registration status: {}", appPathIdentifier, httpResponse.getStatusCode()); } // 根据响应状态码204判断是否注册成功 return httpResponse.getStatusCode() == Status.NO_CONTENT.getStatusCode(); }
// DiscoveryClient构造器中: if (clientConfig.shouldRegisterWithEureka() && clientConfig.shouldEnforceRegistrationAtInit()) { //配置了开启注册和强制注册初始化时,则会立马调用注册方法 try { if (!register() ) { throw new IllegalStateException("Registration error at startup. Invalid server response."); } } catch (Throwable th) { logger.error("Registration error at startup: {}", th.getMessage()); throw new IllegalStateException(th); } } ----------------------------------- // 实例信息复制器初始化,并且启动。 instanceInfoReplicator = new InstanceInfoReplicator( this, instanceInfo, clientConfig.getInstanceInfoReplicationIntervalSeconds(), 2); // burstSize instanceInfoReplicator.start(clientConfig.getInitialInstanceInfoReplicationIntervalSeconds()); // InstanceInfoReplicator.java实现了RUNNABLE,接着看start方法 public void start(int initialDelayMs) { if (started.compareAndSet(false, true)) { instanceInfo.setIsDirty(); // for initial register // 30秒后执行当前对象任务 Future next = scheduler.schedule(this, initialDelayMs, TimeUnit.SECONDS); scheduledPeriodicRef.set(next); } } public void run() { try { // 刷新实例信息 discoveryClient.refreshInstanceInfo(); // 判断实例信息是否发生改变 // isInstanceInfoDirty默认为false,实例信息发生改变时会被设为true // 被设为ture,则dirtyTimestamp不为null,则发起注册请求 Long dirtyTimestamp = instanceInfo.isDirtyWithTime(); if (dirtyTimestamp != null) { // 注册 discoveryClient.register(); instanceInfo.unsetIsDirty(dirtyTimestamp); } } catch (Throwable t) { logger.warn("There was a problem with the instance info replicator", t); } finally { // 40秒后执行 Future next = scheduler.schedule(this, replicationIntervalSeconds, TimeUnit.SECONDS); scheduledPeriodicRef.set(next); } } ------------------------------------ /** * 通过REST调用注册eureka服务 */ boolean register() throws Throwable { logger.info(PREFIX + "{}: registering service...", appPathIdentifier); EurekaHttpResponse<Void> httpResponse; try { httpResponse = eurekaTransport.registrationClient.register(instanceInfo); } catch (Exception e) { logger.warn(PREFIX + "{} - registration failed {}", appPathIdentifier, e.getMessage(), e); throw e; } if (logger.isInfoEnabled()) { logger.info(PREFIX + "{} - registration status: {}", appPathIdentifier, httpResponse.getStatusCode()); } // 根据响应状态码204判断是否注册成功 return httpResponse.getStatusCode() == Status.NO_CONTENT.getStatusCode(); }
■Eureka Client:
1)注册1:DisoverClient构造器里会根据是否开启立即调用注册Eureka Server接口进行注册;
2)注册2:实例信息复制器启动时会使用定时调度30秒延迟调用注册方法,如果实例信息发生改变,则之后会每隔40秒进行重新注册;
3)注册方式:使用Jersey HTTP向Eureka Server发起注册请求。
■Eureka Server:
1)启动:EurekaBootStrap启动入口,继承ServletContextListener。核心类:PeerAwareInstanceRegistryImpl;
2)Eureka Server注册逻辑:服务端本地缓存(队列)进行处理注册,比如:状态的更新、添加到近期变化队列等;
3)复制:集群环境下,节点之间需要进行注册信息的同步。除了本身节点,将会复制注册信息到其它对等节点,最后同样是使用Jersey进行请求同步注册。
本文仅供学习!所有权归属原作者。侵删!文章来源: 搬运工来架构
文章评论