当前位置:   article > 正文

EurekaServer启动

启动eureka

EurekaServer启动

看方法上的注释,初始化eureka,包含eureka集群的同步和发布注册,这个方法时重写ServletContextListener#contextInitialized,是eureka启动的入口了。在 Servlet 容器( 例如 Tomcat、Jetty )启动时,调用 #contextInitialized() 方法。

  1. /**
  2. * Initializes Eureka, including syncing up with other Eureka peers and publishing the registry.
  3. *
  4. * @see
  5. * javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
  6. */
  7. @Override
  8. public void contextInitialized(ServletContextEvent event) {
  9. try {
  10. //初始化eureka环境信息
  11. initEurekaEnvironment();
  12. //初始化eureka的上下文
  13. initEurekaServerContext();
  14. ServletContext sc = event.getServletContext();
  15. sc.setAttribute(EurekaServerContext.class.getName(), serverContext);
  16. } catch (Throwable e) {
  17. logger.error("Cannot bootstrap eureka server :", e);
  18. throw new RuntimeException("Cannot bootstrap eureka server :", e);
  19. }
  20. }

初始化eureka的环境

  1. private static final String TEST = "test";
  2. private static final String ARCHAIUS_DEPLOYMENT_ENVIRONMENT = "archaius.deployment.environment";
  3. private static final String EUREKA_ENVIRONMENT = "eureka.environment";
  4. private static final String CLOUD = "cloud";
  5. private static final String DEFAULT = "default";
  6. private static final String ARCHAIUS_DEPLOYMENT_DATACENTER = "archaius.deployment.datacenter";
  7. private static final String EUREKA_DATACENTER = "eureka.datacenter";
  8. protected void initEurekaEnvironment() throws Exception {
  9. logger.info("Setting the eureka configuration..");
  10. String dataCenter = ConfigurationManager.getConfigInstance().getString(EUREKA_DATACENTER);
  11. if (dataCenter == null) {
  12. logger.info("Eureka data center value eureka.datacenter is not set, defaulting to default");
  13. ConfigurationManager.getConfigInstance().setProperty(ARCHAIUS_DEPLOYMENT_DATACENTER, DEFAULT);
  14. } else {
  15. ConfigurationManager.getConfigInstance().setProperty(ARCHAIUS_DEPLOYMENT_DATACENTER, dataCenter);
  16. }
  17. String environment = ConfigurationManager.getConfigInstance().getString(EUREKA_ENVIRONMENT);
  18. if (environment == null) {
  19. ConfigurationManager.getConfigInstance().setProperty(ARCHAIUS_DEPLOYMENT_ENVIRONMENT, TEST);
  20. logger.info("Eureka environment value eureka.environment is not set, defaulting to test");
  21. }
  22. }

在ConfigurationManager.getConfigInstance()中,其实就是初始化ConfigurationManager的实例

(1)创建一个ConcurrentCompositeConfiguration实例,代表了所谓的配置,包括了eureka需要的所有的配置。在初始化这个实例的时候,调用了clear()方法,fireEvent()发布了一个事件(EVENT_CLEAR),fireEvent()这个方法其实是父类的方法,牵扯比较复杂的另外一个项目(ConfigurationManager本身不是属于eureka的源码,是属于netflix config项目的源码)。

  1. /**
  2. * Creates an empty CompositeConfiguration object which can then
  3. * be added some other Configuration files
  4. */
  5. public ConcurrentCompositeConfiguration()
  6. {
  7. clear();
  8. }
  9. @Override
  10. public final void clear()
  11. {
  12. fireEvent(EVENT_CLEAR, null, null, true);
  13. configList.clear();
  14. namedConfigurations.clear();
  15. // recreate the in memory configuration
  16. containerConfiguration = new ConcurrentMapConfiguration();
  17. containerConfiguration.setThrowExceptionOnMissing(isThrowExceptionOnMissing());
  18. containerConfiguration.setListDelimiter(getListDelimiter());
  19. containerConfiguration.setDelimiterParsingDisabled(isDelimiterParsingDisabled());
  20. containerConfiguration.addConfigurationListener(eventPropagater);
  21. configList.add(containerConfiguration);
  22. overrideProperties = new ConcurrentMapConfiguration();
  23. overrideProperties.setThrowExceptionOnMissing(isThrowExceptionOnMissing());
  24. overrideProperties.setListDelimiter(getListDelimiter());
  25. overrideProperties.setDelimiterParsingDisabled(isDelimiterParsingDisabled());
  26. overrideProperties.addConfigurationListener(eventPropagater);
  27. fireEvent(EVENT_CLEAR, null, null, false);
  28. containerConfigurationChanged = false;
  29. invalidate();
  30. }

(2)就是往上面的那个ConcurrentCompositeConfiguration实例加入了一堆别的config,然后搞完了以后,就直接返回了这个实例,就是作为所谓的那个配置的单例

(3)初始化数据中心的配置,如果没有配置的话,就是DEFAULT data center

(4)初始化eurueka运行的环境,如果你没有配置的话,默认就给你设置为test环境

(5)initEurekaEnvironment的初始化环境的逻辑

初始化eureka的上下文

  1. /**
  2. * init hook for server context. Override for custom logic.
  3. */
  4. protected void initEurekaServerContext() throws Exception {
  5. //加载eureka-server。properties文件的配置
  6. EurekaServerConfig eurekaServerConfig = new DefaultEurekaServerConfig();
  7. // For backward compatibility
  8. JsonXStream.getInstance().registerConverter(new V1AwareInstanceInfoConverter(), XStream.PRIORITY_VERY_HIGH);
  9. XmlXStream.getInstance().registerConverter(new V1AwareInstanceInfoConverter(), XStream.PRIORITY_VERY_HIGH);
  10. logger.info("Initializing the eureka client...");
  11. logger.info(eurekaServerConfig.getJsonCodecName());
  12. ServerCodecs serverCodecs = new DefaultServerCodecs(eurekaServerConfig);
  13. //初始化一个ApplicationInfoManager,对应的其实是一个eureka-client。
  14. ApplicationInfoManager applicationInfoManager = null;
  15. //初始化eureka-server内部的一个eureka-client,用来和其他eureka-server节点用来注册通信的
  16. if (eurekaClient == null) {
  17. //CommonConstants. 用来获取client信息
  18. EurekaInstanceConfig instanceConfig = isCloud(ConfigurationManager.getDeploymentContext())
  19. ? new CloudInstanceConfig()
  20. : new MyDataCenterInstanceConfig();
  21. applicationInfoManager = new ApplicationInfoManager(
  22. instanceConfig, new EurekaConfigBasedInstanceInfoProvider(instanceConfig).get());
  23. EurekaClientConfig eurekaClientConfig = new DefaultEurekaClientConfig();
  24. eurekaClient = new DiscoveryClient(applicationInfoManager, eurekaClientConfig);
  25. } else {
  26. applicationInfoManager = eurekaClient.getApplicationInfoManager();
  27. }
  28. //处理注册的相关事情
  29. PeerAwareInstanceRegistry registry;
  30. if (isAws(applicationInfoManager.getInfo())) {
  31. registry = new AwsInstanceRegistry(
  32. eurekaServerConfig,
  33. eurekaClient.getEurekaClientConfig(),
  34. serverCodecs,
  35. eurekaClient
  36. );
  37. awsBinder = new AwsBinderDelegate(eurekaServerConfig, eurekaClient.getEurekaClientConfig(), registry, applicationInfoManager);
  38. awsBinder.start();
  39. } else {
  40. registry = new PeerAwareInstanceRegistryImpl(
  41. eurekaServerConfig,
  42. eurekaClient.getEurekaClientConfig(),
  43. serverCodecs,
  44. eurekaClient
  45. );
  46. }
  47. //处理peer节点
  48. PeerEurekaNodes peerEurekaNodes = getPeerEurekaNodes(
  49. registry,
  50. eurekaServerConfig,
  51. eurekaClient.getEurekaClientConfig(),
  52. serverCodecs,
  53. applicationInfoManager
  54. );
  55. //完成eureka-server上下文的构建以及初始化过程
  56. serverContext = new DefaultEurekaServerContext(
  57. eurekaServerConfig,
  58. serverCodecs,
  59. registry,
  60. peerEurekaNodes,
  61. applicationInfoManager
  62. );
  63. EurekaServerContextHolder.initialize(serverContext);
  64. serverContext.initialize();
  65. logger.info("Initialized server context");
  66. // 第六步,处理一点善后的事情,从相邻的eureka节点拷贝注册信息
  67. int registryCount = registry.syncUp();
  68. //这个方法就是打开注册表,可以接收请求
  69. registry.openForTraffic(applicationInfoManager, registryCount);
  70. // 注册所有的监控
  71. EurekaMonitors.registerAllStats();
  72. }
配置文件读取
  1. public DefaultEurekaServerConfig() {
  2. init();
  3. }
  4. private void init() {
  5. String env = ConfigurationManager.getConfigInstance().getString(
  6. EUREKA_ENVIRONMENT, TEST);
  7. ConfigurationManager.getConfigInstance().setProperty(
  8. ARCHAIUS_DEPLOYMENT_ENVIRONMENT, env);
  9. String eurekaPropsFile = EUREKA_PROPS_FILE.get();
  10. try {
  11. // ConfigurationManager
  12. // .loadPropertiesFromResources(eurekaPropsFile);
  13. ConfigurationManager
  14. .loadCascadedPropertiesFromResources(eurekaPropsFile);
  15. } catch (IOException e) {
  16. logger.warn(
  17. "Cannot find the properties specified : {}. This may be okay if there are other environment "
  18. + "specific properties or the configuration is installed with a different mechanism.",
  19. eurekaPropsFile);
  20. }
  21. }

加载eureka-server.properties的过程:

(1)创建了一个DefaultEurekaServerConfig对象

(2)创建DefaultEurekaServerConfig对象的时候,在里面会有一个init方法

(3)先是将eureka-server.properties中的配置加载到了一个Properties对象中,然后将Properties对象中的配置放到ConfigurationManager中去,此时ConfigurationManager中去就有了所有的配置了

(4)然后DefaultEurekaServerConfig提供的获取配置项的各个方法,都是通过硬编码的配置项名称,从DynamicPropertyFactory中获取配置项的值,DynamicPropertyFactory是从ConfigurationManager那儿来的,所以也包含了所有配置项的值

(5)在获取配置项的时候,如果没有配置,那么就会有默认的值,全部属性都是有默认值的

创建 Eureka-Server 请求和响应编解码器
  1. logger.info("Initializing the eureka client...");
  2. logger.info(eurekaServerConfig.getJsonCodecName());
  3. ServerCodecs serverCodecs = new DefaultServerCodecs(eurekaServerConfig);
创建Eureka-Client
  1. //初始化一个ApplicationInfoManager,对应的其实是一个eureka-client。
  2. ApplicationInfoManager applicationInfoManager = null;
  3. //初始化eureka-server内部的一个eureka-client,用来和其他eureka-server节点用来注册通信的
  4. if (eurekaClient == null) {
  5. //CommonConstants. 用来获取client信息
  6. EurekaInstanceConfig instanceConfig = isCloud(ConfigurationManager.getDeploymentContext())
  7. ? new CloudInstanceConfig()
  8. : new MyDataCenterInstanceConfig();
  9. applicationInfoManager = new ApplicationInfoManager(
  10. instanceConfig, new EurekaConfigBasedInstanceInfoProvider(instanceConfig).get());
  11. EurekaClientConfig eurekaClientConfig = new DefaultEurekaClientConfig();
  12. eurekaClient = new DiscoveryClient(applicationInfoManager, eurekaClientConfig);
  13. } else {
  14. applicationInfoManager = eurekaClient.getApplicationInfoManager();
  15. }

在new MyDataCenterInstanceConfig()这个无参构造中,最终会去读取eureka-client.properties的配置,去提供一些默认值。

image-20211008155824162

因为eureka-server本身也是一个eureka-client,因为当组成集群的时候,它自己也要向别的服务端进行注册

  1. //处理注册的相关事情
  2. PeerAwareInstanceRegistry registry;
  3. if (isAws(applicationInfoManager.getInfo())) {
  4. registry = new AwsInstanceRegistry(
  5. eurekaServerConfig,
  6. eurekaClient.getEurekaClientConfig(),
  7. serverCodecs,
  8. eurekaClient
  9. );
  10. awsBinder = new AwsBinderDelegate(eurekaServerConfig, eurekaClient.getEurekaClientConfig(), registry, applicationInfoManager);
  11. awsBinder.start();
  12. } else {
  13. registry = new PeerAwareInstanceRegistryImpl(
  14. eurekaServerConfig,
  15. eurekaClient.getEurekaClientConfig(),
  16. serverCodecs,
  17. eurekaClient
  18. );
  19. }
  20. //处理peer节点
  21. PeerEurekaNodes peerEurekaNodes = getPeerEurekaNodes(
  22. registry,
  23. eurekaServerConfig,
  24. eurekaClient.getEurekaClientConfig(),
  25. serverCodecs,
  26. applicationInfoManager
  27. );
  28. //完成eureka-server上下文的构建以及初始化过程
  29. serverContext = new DefaultEurekaServerContext(
  30. eurekaServerConfig,
  31. serverCodecs,
  32. registry,
  33. peerEurekaNodes,
  34. applicationInfoManager
  35. );
初始化 EurekaServerContextHolder
EurekaServerContextHolder.initialize(serverContext);
初始化 Eureka-Server 上下文
  1. @PostConstruct
  2. @Override
  3. public void initialize() {
  4. logger.info("Initializing ...");
  5. //启动 Eureka-Server 集群节点集合(复制)
  6. peerEurekaNodes.start();
  7. try {
  8. // 初始化 应用实例信息的注册表
  9. registry.init(peerEurekaNodes);
  10. } catch (Exception e) {
  11. throw new RuntimeException(e);
  12. }
  13. logger.info("Initialized");
  14. }
从其他 Eureka-Server 拉取注册信息
  1. // 第六步,处理一点善后的事情,从相邻的eureka节点拷贝注册信息
  2. int registryCount = registry.syncUp();
  3. //这个方法就是打开注册表,可以接收请求
  4. registry.openForTraffic(applicationInfoManager, registryCount);
注册监控
EurekaMonitors.registerAllStats();
声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号