这个start方法中开启了一个新的线程,然后进行一些Eureka Server的初始化工作,比如调用eurekaServerBootstrap的contextInitialized方法,EurekaServerBootstrap代码如下:
public class EurekaServerBootstrap { // 此处省略部分代码 public void contextInitialized(ServletContext context) { try { // 初始化Eureka的环境变量 initEurekaEnvironment(); // 初始化Eureka的上下文 initEurekaServerContext(); context.setAttribute(EurekaServerContext.class.getName(), this.serverContext); } catch (Throwable e) { log.error("Cannot bootstrap eureka server :", e); throw new RuntimeException("Cannot bootstrap eureka server :", e); } } protected void initEurekaEnvironment() throws Exception { log.info("Setting the eureka configuration.."); String dataCenter = ConfigurationManager.getConfigInstance() .getString(EUREKA_DATACENTER); if (dataCenter == null) { log.info( "Eureka data center value eureka.datacenter is not set, defaulting to default"); ConfigurationManager.getConfigInstance() .setProperty(ARCHAIUS_DEPLOYMENT_DATACENTER, DEFAULT); } else { ConfigurationManager.getConfigInstance() .setProperty(ARCHAIUS_DEPLOYMENT_DATACENTER, dataCenter); } String environment = ConfigurationManager.getConfigInstance() .getString(EUREKA_ENVIRONMENT); if (environment == null) { ConfigurationManager.getConfigInstance() .setProperty(ARCHAIUS_DEPLOYMENT_ENVIRONMENT, TEST); log.info( "Eureka environment value eureka.environment is not set, defaulting to test"); } else { ConfigurationManager.getConfigInstance() .setProperty(ARCHAIUS_DEPLOYMENT_ENVIRONMENT, environment); } } protected void initEurekaServerContext() throws Exception { // For backward compatibility JsonXStream.getInstance().registerConverter(new V1AwareInstanceInfoConverter(), XStream.PRIORITY_VERY_HIGH); XmlXStream.getInstance().registerConverter(new V1AwareInstanceInfoConverter(), XStream.PRIORITY_VERY_HIGH); if (isAws(this.applicationInfoManager.getInfo())) { this.awsBinder = new AwsBinderDelegate(this.eurekaServerConfig, this.eurekaClientConfig, this.registry, this.applicationInfoManager); this.awsBinder.start(); } //初始化eureka server上下文 EurekaServerContextHolder.initialize(this.serverContext); log.info("Initialized server context"); // Copy registry from neighboring eureka node // 从相邻的eureka节点复制注册表 int registryCount = this.registry.syncUp(); // 默认每30秒发送心跳,1分钟就是2次 // 修改eureka状态为up // 同时,这里面会开启一个定时任务,用于清理 60秒没有心跳的客户端。自动下线 this.registry.openForTraffic(this.applicationInfoManager, registryCount); // Register all monitoring statistics. EurekaMonitors.registerAllStats(); } public void contextDestroyed(ServletContext context) { try { log.info("Shutting down Eureka Server.."); context.removeAttribute(EurekaServerContext.class.getName()); destroyEurekaServerContext(); destroyEurekaEnvironment(); } catch (Throwable e) { log.error("Error shutting down eureka", e); } log.info("Eureka Service is now shutdown..."); } }在初始化Eureka Server上下文环境后,就会继续执行openForTraffic方法,这个方法主要是设置了期望每分钟接收到的心跳次数,并将服务实例的状态设置为UP,最后又通过方法postInit来开启一个定时任务,用于每隔一段时间(默认60秒)将没有续约的服务实例(默认90秒没有续约)清理掉。openForTraffic的方法代码如下:
@Override public void openForTraffic(ApplicationInfoManager applicationInfoManager, int count) { // Renewals happen every 30 seconds and for a minute it should be a factor of 2. // 计算每分钟最大续约数 this.expectedNumberOfRenewsPerMin = count * 2; // 计算每分钟最小续约数 this.numberOfRenewsPerMinThreshold = (int) (this.expectedNumberOfRenewsPerMin * serverConfig.getRenewalPercentThreshold()); logger.info("Got {} instances from neighboring DS node", count); logger.info("Renew threshold is: {}", numberOfRenewsPerMinThreshold); this.startupTime = System.currentTimeMillis(); if (count > 0) { this.peerInstancesTransferEmptyOnStartup = false; } DataCenterInfo.Name selfName = applicationInfoManager.getInfo().getDataCenterInfo().getName(); boolean isAws = Name.Amazon == selfName; if (isAws && serverConfig.shouldPrimeAwsReplicaConnections()) { logger.info("Priming AWS connections for all replicas.."); primeAwsReplicas(applicationInfoManager); } logger.info("Changing status to UP"); // 修改服务实例的状态为UP applicationInfoManager.setInstanceStatus(InstanceStatus.UP); // 开启定时任务,每隔一段时间(默认60秒)将没有续约的服务实例(默认90秒没有续约)清理掉 super.postInit(); }