zoukankan      html  css  js  c++  java
  • Spring Cloud Netflix Eureka client源码分析

    1.client端

    EurekaClient提供三个功能:

    EurekaClient API contracts are:
    * - provide the ability to get InstanceInfo(s) (in various different ways)
    * - provide the ability to get data about the local Client (known regions, own AZ etc)
    * - provide the ability to register and access the healthcheck handler for the client

    使用@EnableEurekaClient起效,其定义如下:

    /**
     * Convenience annotation for clients to enable Eureka discovery configuration
     * (specifically). Use this (optionally) in case you want discovery and know for sure that
     * it is Eureka you want. All it does is turn on discovery and let the autoconfiguration
     * find the eureka classes if they are available (i.e. you need Eureka on the classpath as
     * well).
     *
     * @author Dave Syer
     * @author Spencer Gibb
     */
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @EnableDiscoveryClient
    public @interface EnableEurekaClient {
    
    }

    注册

    /**
     * Annotation to enable a DiscoveryClient implementation.
     * @author Spencer Gibb
     */
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @Import(EnableDiscoveryClientImportSelector.class)
    public @interface EnableDiscoveryClient {
    
        /**
         * If true, the ServiceRegistry will automatically register the local server.
         */
        boolean autoRegister() default true;
    }
    EnableDiscoveryClientImportSelector继承自SpringFactoryImportSelector,在容器启动时触发,前文已经有介绍执行路径:

    在其父类org.springframework.cloud.commons.util.SpringFactoryImportSelector
    的String[] selectImports(AnnotationMetadata metadata)方法中正是根据这个标记类判定是否加载如下定义的类。

    @Override
        public String[] selectImports(AnnotationMetadata metadata) {
            if (!isEnabled()) {
                return new String[0];
            }
            AnnotationAttributes attributes = AnnotationAttributes.fromMap(
                    metadata.getAnnotationAttributes(this.annotationClass.getName(), true));
    
            Assert.notNull(attributes, "No " + getSimpleName() + " attributes found. Is "
                    + metadata.getClassName() + " annotated with @" + getSimpleName() + "?");
    
            // Find all possible auto configuration classes, filtering duplicates
            List<String> factories = new ArrayList<>(new LinkedHashSet<>(SpringFactoriesLoader
                    .loadFactoryNames(this.annotationClass, this.beanClassLoader)));
    
            if (factories.isEmpty() && !hasDefaultFactory()) {
                throw new IllegalStateException("Annotation @" + getSimpleName()
                        + " found, but there are no implementations. Did you forget to include a starter?");
            }
    
            if (factories.size() > 1) {
                // there should only ever be one DiscoveryClient, but there might be more than
                // one factory
                log.warn("More than one implementation " + "of @" + getSimpleName()
                        + " (now relying on @Conditionals to pick one): " + factories);
            }
    
            return factories.toArray(new String[factories.size()]);
        }

    SpringFactoriesLoader调用loadFactoryNames其实加载META-INF/spring.factories下的class。

    spring-cloud-netflix-eureka-clientsrcmain esourcesMETA-INFspring.factories中配置:

     1.1.1 定义HasFeatures Bean

        @Bean
        public HasFeatures eurekaFeature() {
            return HasFeatures.namedFeature("Eureka Client", EurekaClient.class);
        }

    1.1.2 定义EurekaClientConfigBean bean

        @Bean
        @ConditionalOnMissingBean(value = EurekaClientConfig.class, search = SearchStrategy.CURRENT)
        public EurekaClientConfigBean eurekaClientConfigBean() {
            EurekaClientConfigBean client = new EurekaClientConfigBean();
            if ("bootstrap".equals(this.env.getProperty("spring.config.name"))) {
                // We don't register during bootstrap by default, but there will be another
                // chance later.
                client.setRegisterWithEureka(false);
            }
            return client;
        }

    1.1.3 定义EurekaInstanceConfigBean bean

    @Bean
        @ConditionalOnMissingBean(value = EurekaInstanceConfig.class, search = SearchStrategy.CURRENT)
        public EurekaInstanceConfigBean eurekaInstanceConfigBean(InetUtils inetUtils) {
            EurekaInstanceConfigBean instance = new EurekaInstanceConfigBean(inetUtils);
            instance.setNonSecurePort(this.nonSecurePort);
            instance.setInstanceId(getDefaultInstanceId(this.env));
    
            if (this.managementPort != this.nonSecurePort && this.managementPort != 0) {
                if (StringUtils.hasText(this.hostname)) {
                    instance.setHostname(this.hostname);
                }
                RelaxedPropertyResolver relaxedPropertyResolver = new RelaxedPropertyResolver(env, "eureka.instance.");
                String statusPageUrlPath = relaxedPropertyResolver.getProperty("statusPageUrlPath");
                String healthCheckUrlPath = relaxedPropertyResolver.getProperty("healthCheckUrlPath");
                if (StringUtils.hasText(statusPageUrlPath)) {
                    instance.setStatusPageUrlPath(statusPageUrlPath);
                }
                if (StringUtils.hasText(healthCheckUrlPath)) {
                    instance.setHealthCheckUrlPath(healthCheckUrlPath);
                }
                String scheme = instance.getSecurePortEnabled() ? "https" : "http";
                instance.setStatusPageUrl(scheme + "://" + instance.getHostname() + ":"
                        + this.managementPort + instance.getStatusPageUrlPath());
                instance.setHealthCheckUrl(scheme + "://" + instance.getHostname() + ":"
                        + this.managementPort + instance.getHealthCheckUrlPath());
            }
            return instance;
        }

    1.1.4 定义DiscoveryClient bean

        @Bean
        public DiscoveryClient discoveryClient(EurekaInstanceConfig config,
                EurekaClient client) {
            return new EurekaDiscoveryClient(config, client);
        }

    1.1.5 定义EurekaServiceRegistry bean

        @Bean
        public EurekaServiceRegistry eurekaServiceRegistry() {
            return new EurekaServiceRegistry();
        }

    1.1.6 定义EurekaRegistration bean

        @Bean
        @ConditionalOnBean(AutoServiceRegistrationProperties.class)
        @ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)
        public EurekaRegistration eurekaRegistration(EurekaClient eurekaClient, CloudEurekaInstanceConfig instanceConfig, ApplicationInfoManager applicationInfoManager) {
            return EurekaRegistration.builder(instanceConfig)
                    .with(applicationInfoManager)
                    .with(eurekaClient)
                    .with(healthCheckHandler)
                    .build();
        }

    1.1.7 定义EurekaAutoServiceRegistration bean

        @Bean
        @ConditionalOnBean(AutoServiceRegistrationProperties.class)
        @ConditionalOnProperty(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);
        }

    1.2 EurekaClientConfiguration
    1.2.1 定义
    EurekaClient bean
            @Bean(destroyMethod = "shutdown")
            @ConditionalOnMissingBean(value = EurekaClient.class, search = SearchStrategy.CURRENT)
            public EurekaClient eurekaClient(ApplicationInfoManager manager,
                    EurekaClientConfig config) {
                return new CloudEurekaClient(manager, config, this.optionalArgs,
                        this.context);
            }

    1.2.2 定义ApplicationInfoManager bean

            @Bean
            @ConditionalOnMissingBean(value = ApplicationInfoManager.class, search = SearchStrategy.CURRENT)
            public ApplicationInfoManager eurekaApplicationInfoManager(
                    EurekaInstanceConfig config) {
                InstanceInfo instanceInfo = new InstanceInfoFactory().create(config);
                return new ApplicationInfoManager(config, instanceInfo);
            }

    1.3 RefreshableEurekaClientConfiguration

    1.3.1 定义EurekaClient bean

            @Bean(destroyMethod = "shutdown")
            @ConditionalOnMissingBean(value = EurekaClient.class, search = SearchStrategy.CURRENT)
            @org.springframework.cloud.context.config.annotation.RefreshScope
            @Lazy
            public EurekaClient eurekaClient(ApplicationInfoManager manager,
                    EurekaClientConfig config, EurekaInstanceConfig instance) {
                manager.getInfo(); // force initialization
                return new CloudEurekaClient(manager, config, this.optionalArgs,
                        this.context);
            }

    1.3.2 定义ApplicationInfoManager

            @Bean
            @ConditionalOnMissingBean(value = ApplicationInfoManager.class, search = SearchStrategy.CURRENT)
            @org.springframework.cloud.context.config.annotation.RefreshScope
            @Lazy
            public ApplicationInfoManager eurekaApplicationInfoManager(
                    EurekaInstanceConfig config) {
                InstanceInfo instanceInfo = new InstanceInfoFactory().create(config);
                return new ApplicationInfoManager(config, instanceInfo);
            }
    参考文献:
    http://blog.csdn.net/neosmith/article/details/53131023




  • 相关阅读:
    085 Maximal Rectangle 最大矩形
    084 Largest Rectangle in Histogram 柱状图中最大的矩形
    083 Remove Duplicates from Sorted List 有序链表中删除重复的结点
    082 Remove Duplicates from Sorted List II 有序的链表删除重复的结点 II
    081 Search in Rotated Sorted Array II 搜索旋转排序数组 ||
    080 Remove Duplicates from Sorted Array II 从排序阵列中删除重复 II
    079 Word Search 单词搜索
    078 Subsets 子集
    bzoj2326: [HNOI2011]数学作业
    bzoj2152: 聪聪可可
  • 原文地址:https://www.cnblogs.com/davidwang456/p/6347168.html
Copyright © 2011-2022 走看看