Eureka服务端源码-初始化


Eureka服务端初始化

  1. 项目依赖中会依赖spring-cloud-netflix-eureka-server 找到spring.factories文件

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
      org.springframework.cloud.netflix.eureka.server.EurekaServerAutoConfiguration
    
  2. 以下是EurekaServerAutoConfiguration自动配置类

    @Configuration(proxyBeanMethods = false)
    //EurekaServer初始化配置
    @Import(EurekaServerInitializerConfiguration.class)
    //对于EurekaServerMarkerConfiguration 这个就是一个标识  在@EurekaServer注册里面也进行了import
    //在启动的时候EurekaServerMarkerConfiguration.Marker就会存在
    @ConditionalOnBean(EurekaServerMarkerConfiguration.Marker.class)
    @EnableConfigurationProperties({ EurekaDashboardProperties.class,
    		InstanceRegistryProperties.class })
    @PropertySource("classpath:/eureka/server.properties")
    public class EurekaServerAutoConfiguration implements WebMvcConfigurer {
    	@Bean
    	public PeerAwareInstanceRegistry peerAwareInstanceRegistry(
    			ServerCodecs serverCodecs) {
    		this.eurekaClient.getApplications(); // force initialization
    		return new InstanceRegistry(this.eurekaServerConfig, this.eurekaClientConfig,
    				serverCodecs, this.eurekaClient,
    				this.instanceRegistryProperties.getExpectedNumberOfClientsSendingRenews(),
    				this.instanceRegistryProperties.getDefaultOpenForTrafficCount());
    	}
    
      //EurekaServer对应的节点信息
    	@Bean
    	@ConditionalOnMissingBean
    	public PeerEurekaNodes peerEurekaNodes(PeerAwareInstanceRegistry registry,
    			ServerCodecs serverCodecs,
    			ReplicationClientAdditionalFilters replicationClientAdditionalFilters) {
    		return new RefreshablePeerEurekaNodes(registry, this.eurekaServerConfig,
    				this.eurekaClientConfig, serverCodecs, this.applicationInfoManager,
    				replicationClientAdditionalFilters);
    	}
      
    	@Bean
    	public EurekaServerBootstrap eurekaServerBootstrap(PeerAwareInstanceRegistry registry,
    			EurekaServerContext serverContext) {
    		return new EurekaServerBootstrap(this.applicationInfoManager,
    				this.eurekaClientConfig, this.eurekaServerConfig, registry,
    				serverContext);
    	}
    
    @Configuration(proxyBeanMethods = false)
    public class EurekaServerInitializerConfiguration
    		implements ServletContextAware, SmartLifecycle, Ordered {
    	@Override
    	public void start() {
    		new Thread(() -> {
    			try {
            // eurekaServerBootstrap在EurekaServerAutoConfiguration已经进行了初始化
    				eurekaServerBootstrap.contextInitialized(
    						EurekaServerInitializerConfiguration.this.servletContext);
    				log.info("Started Eureka Server");
    			}
    			catch (Exception ex) {
    			}
    		}).start();
    	}
    }
    

    EventServerBootStrap类中的contextInitialized方法

    public void contextInitialized(ServletContext context) {
      try {
        //设置一些eureka的配置信息
        initEurekaEnvironment();
        //初始化Eureka Server context,也会从临近的eureka server 节点copy对应的注册信息
    		// int registryCount = this.registry.syncUp();
        initEurekaServerContext();
      }
    }
    

    对于EurekaServerContext的初始化如下

    @Bean
    @ConditionalOnMissingBean
    public EurekaServerContext eurekaServerContext(ServerCodecs serverCodecs,
    			PeerAwareInstanceRegistry registry, PeerEurekaNodes peerEurekaNodes) {
    		return new DefaultEurekaServerContext(this.eurekaServerConfig, serverCodecs,
    				registry, peerEurekaNodes, this.applicationInfoManager);
    }
    

    DefaultEurekaServerContext中核心代码如下:

    /**
     * 表示本地server 上下文,并提供组件的get方法
     */
    @Singleton
    public class DefaultEurekaServerContext implements EurekaServerContext {
        //省去了构造器和一些getter等方法
        @PostConstruct
        @Override
        public void initialize() {
            //eureka server节点启动
            peerEurekaNodes.start();
            try {
                //registry初始化,具体执行的试PeerAwareInstanceRegistryImpl#init方法
                registry.init(peerEurekaNodes);
            }
        }
    }
    

    PeerEurekaNodes#start详解

    默认情况下 每10分钟定时更新PeerEurekaNode

    public void start() {
      //任务执行器
      taskExecutor = Executors.newSingleThreadScheduledExecutor(
        new ThreadFactory() {
          @Override
          public Thread newThread(Runnable r) {
            Thread thread = new Thread(r, "Eureka-PeerNodesUpdater");
            thread.setDaemon(true);
            return thread;
          }
        }
      );
      try {
        //更新节点信息
        updatePeerEurekaNodes(resolvePeerUrls());
        Runnable peersUpdateTask = new Runnable() {
          @Override
          public void run() {
            try {
              updatePeerEurekaNodes(resolvePeerUrls());
            } catch (Throwable e) {
              logger.error("Cannot update the replica Nodes", e);
            }
          }
        };
        //定时更新节点信息
        taskExecutor.scheduleWithFixedDelay(
          peersUpdateTask,
          //Eureka节点之间更新信息 默认试10分钟
          serverConfig.getPeerEurekaNodesUpdateIntervalMs(),
          serverConfig.getPeerEurekaNodesUpdateIntervalMs(),
          TimeUnit.MILLISECONDS
        );
      }
    }
    

    PeerAwareInstanceRegistryImpl#init方法详解

    @Override
    public void init(PeerEurekaNodes peerEurekaNodes) throws Exception {
      this.numberOfReplicationsLastMin.start();
      this.peerEurekaNodes = peerEurekaNodes;
      initializedResponseCache();
      //定时更新租约阀值
      scheduleRenewalThresholdUpdateTask();
      //如果配置了远程region,则把远程region的中设置到regionNameVSRemoteRegistry
      initRemoteRegionRegistry();
    }
    
  3. 总结

    • EurekaServer端加入了@EnableEurekaServer ,则会创建bean EurekaServerMarkerConfiguration.Marker
    • 有了Markerbean了,也就是激活了EurekaServerAutoConfiguration,在该类中创建EurekaServerBootstrap、PeerAwareInstanceRegistry、PeerEurekaNodes、EurekaServerContext等核心类
    • EurekaServerBootstrap会做一些初始化动作 eurekaServer上下文初始化设置等
    • EurekaServerContext进行创建初始化的时候:启动peerEurekaNodes、初始化PeerAwareInstanceRegistry