zoukankan      html  css  js  c++  java
  • @EnableDiscoveryClient与Nacos的服务注册与拉取

    ​  前一阵看到有篇博客说cloud从Edgware版本开始,可以不加@EnableDiscoveryClient注解,只要配置好注册中心的相关配置即可自动开启服务注册功能,比较好奇其中的原理,研究了一番特意记录下来



    环境:
    SpringBoot: 2.3.5
    SpringCloud: Hoxton.SR8
    SpringCloudAlibaba: 2.2.3


    配置信息:

    @SpringBootApplication
    //autoRegiste属性值默认为true可以不配置此属性
    @EnableDiscoveryClient(autoRegister = true)
    public class NacosApplication {
        
        public static void main(String[] args) {
            SpringApplication.run(NacosApplication.class, args);
        }
        
    }
    
    spring:
      application:
        name: nacosTest
      cloud:
        nacos:
          discovery:
            enabled: true(默认为true,可以不配置此属性)
            server-addr: 192.168.1.10:8848
            username: nacos
            password: nacos
    

    配置的作用:

    nacos.discovery.enabled: 开启服务的注册与发现功能;
    注册成功后可以在nacos的web端界面看到服务的相关信息
    image
    同时,具备拉取服务信息的功能, discoveryClient.getInstances()方法可以返回服务的详细配置信息

    @Resource
    private DiscoveryClient discoveryClient;
    
    @GetMapping("/client")
    public List<ServiceInstance> client() {
        return discoveryClient.getInstances("服务名称");
    }
    

    @EnableDiscoveryClient(autoRegister = true); 开启服务自动注册功能,项目启动后能在nacos的web端界面看到服务的相关信息,并且具备拉取服务信息的功能(前提是nacos.discovery.enabled不为false)
    @EnableDiscoveryClient(autoRegister = false); 关闭服务自动注册功能, 项目启动后nacos的web端界面没有此项目的信息,但是依然具备拉取服务信息的功能(前提是nacos.discovery.enabled不为false)


    实现逻辑:

    @EnableDiscoveryClient

    打开@EnableDiscoveryClient注解(代码里只保留了重点)

    @Import(EnableDiscoveryClientImportSelector.class)
    public @interface EnableDiscoveryClient {
    	boolean autoRegister() default true;
    }
    

    进入EnableDiscoveryClientImportSelector类

    @Override
    public String[] selectImports(AnnotationMetadata metadata) {
        String[] imports = super.selectImports(metadata);
    
        AnnotationAttributes attributes = AnnotationAttributes.fromMap(
            metadata.getAnnotationAttributes(getAnnotationClass().getName(), true));
    	//获取@EnableDiscoveryClient的autoRegister属性
        boolean autoRegister = attributes.getBoolean("autoRegister");
    	//开启自动注册的话,将AutoServiceRegistrationConfiguration类的全限定名返回,会被spring加载到bean容器
        if (autoRegister) {
            List<String> importsList = new ArrayList<>(Arrays.asList(imports));
            importsList.add(
                "org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration");
            imports = importsList.toArray(new String[0]);
        }
        //关闭自动注册的话,将***.auto-registration.enabled设置为false,放入环境属性中(其他地方会用到)
        else {
            Environment env = getEnvironment();
            if (ConfigurableEnvironment.class.isInstance(env)) {
                ConfigurableEnvironment configEnv = (ConfigurableEnvironment) env;
                LinkedHashMap<String, Object> map = new LinkedHashMap<>();
                map.put("spring.cloud.service-registry.auto-registration.enabled", false);
                MapPropertySource propertySource = new MapPropertySource(
                    "springCloudDiscoveryClient", map);
                configEnv.getPropertySources().addLast(propertySource);
            }
        }
        return imports;
    }
    

    既然开启自动注册服务会返回一个叫AutoServiceRegistrationConfiguration的类,那就打开看一下:
    此类是实现自动注册的入口,具体的逻辑在由注册中心实现(如NacosEureka...)

    //当**.registration.enabled属性为true时,此配置类会被加载
    //spring-cloud-commons.jar包内的spring-configuration-metadata.json定义了此属性默认为true
    //即: 不配置@EnableDiscoveryClient或者配置@EnableDiscoveryClient设置autoRegister为true时
    //AutoServiceRegistrationConfiguration会被加载,当@EnableDiscoveryClient设置autoRegister
    //属性为false时,此配置类不会被加载
    @Configuration(proxyBeanMethods = false)
    @EnableConfigurationProperties(AutoServiceRegistrationProperties.class)
    @ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled",
    		matchIfMissing = true)
    public class AutoServiceRegistrationConfiguration {
    
    }
    

    到现在似乎还没发现太多有用的信息,那继续看Nacos的源码

    Nacos:

    找到nacos的spring.factories文件,这是配置自动配置类的地方,文件路径:
    spring-cloud-starter-alibaba-nacos-discovery.jar/META-INF/spring.factories
    文件信息:

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=
      com.alibaba.cloud.nacos.discovery.NacosDiscoveryAutoConfiguration,
      com.alibaba.cloud.nacos.ribbon.RibbonNacosAutoConfiguration,
      com.alibaba.cloud.nacos.endpoint.NacosDiscoveryEndpointAutoConfiguration,
      com.alibaba.cloud.nacos.registry.NacosServiceRegistryAutoConfiguration,
      com.alibaba.cloud.nacos.discovery.NacosDiscoveryClientConfiguration,
      com.alibaba.cloud.nacos.discovery.reactive.NacosReactiveDiscoveryClientConfiguration,
      com.alibaba.cloud.nacos.discovery.configclient.NacosConfigServerAutoConfiguration,
      com.alibaba.cloud.nacos.NacosServiceAutoConfiguration
    org.springframework.cloud.bootstrap.BootstrapConfiguration=
      com.alibaba.cloud.nacos.discovery.configclient.NacosDiscoveryClientConfigServiceBootstrapConfiguration
    

    既然有BootstrapConfiguration,那就先看最后一行的NacosDiscoveryClientConfigServiceBootstrapConfiguration

    //删减了部分代码,便于阅读
    @ImportAutoConfiguration({NacosDiscoveryClientConfiguration.class})
    public class NacosDiscoveryClientConfigServiceBootstrapConfiguration {
    
    }
    

    继续进入NacosDiscoveryClientConfiguration

    //删减了部分代码,便于阅读
    //spring.cloud.nacos.discovery.enabled=true时,此配置类才会加载
    @ConditionalOnNacosDiscoveryEnabled
    @AutoConfigureAfter(NacosDiscoveryAutoConfiguration.class)
    public class NacosDiscoveryClientConfiguration {
    	@Bean
    	public DiscoveryClient nacosDiscoveryClient(NacosServiceDiscovery nacosServiceDiscovery) {
    		return new NacosDiscoveryClient(nacosServiceDiscovery);
    	}
    }
    

    此配置类注入了一个bean: NacosDiscoveryClient, 这个类实现了DiscoveryClient接口, 我们上边的测试用例
    discoveryClient.getInstances("服务名称"), 调用的getInstances方法,实际上就是调用了Nacos官方提供的NacosDiscoveryClient重写的getInstances方法,
    至此,Nacos的的服务拉取搞明白了: 无论是否配置@EnableDiscoveryClient,只要spring.cloud.nacos.discovery.enabled不设置为false,服务就具有拉取注册中心信息的功能

    那服务注册功能呢? 返回spring.factories打开第五行的类: NacosServiceRegistryAutoConfiguration
    服务自动注册逻辑:

    @Configuration(proxyBeanMethods = false)
    @EnableConfigurationProperties
    //确保spring.cloud.nacos.discovery.enabled为true(开启nacos的服务注册与发现功能)
    @ConditionalOnNacosDiscoveryEnabled
    //默认为true,使用@EnableDiscoveryClient注解配置autoRegister为false时,次属性值为false
    //即: 此类不被加载,即: 服务不具备自动注册功能
    @ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled",
    		matchIfMissing = true)
    @AutoConfigureAfter({ AutoServiceRegistrationConfiguration.class,
    		AutoServiceRegistrationAutoConfiguration.class,
    		NacosDiscoveryAutoConfiguration.class })
    public class NacosServiceRegistryAutoConfiguration {
    
    	@Bean
    	public NacosServiceRegistry nacosServiceRegistry(
    			NacosDiscoveryProperties nacosDiscoveryProperties) {
    		return new NacosServiceRegistry(nacosDiscoveryProperties);
    	}
    
    	@Bean
    	@ConditionalOnBean(AutoServiceRegistrationProperties.class)
    	public NacosRegistration nacosRegistration(
    			ObjectProvider<List<NacosRegistrationCustomizer>> registrationCustomizers,
    			NacosDiscoveryProperties nacosDiscoveryProperties,
    			ApplicationContext context) {
    		return new NacosRegistration(registrationCustomizers.getIfAvailable(),
    				nacosDiscoveryProperties, context);
    	}
    
    	@Bean
    	@ConditionalOnBean(AutoServiceRegistrationProperties.class)
    	public NacosAutoServiceRegistration nacosAutoServiceRegistration(
    			NacosServiceRegistry registry,
    			AutoServiceRegistrationProperties autoServiceRegistrationProperties,
    			NacosRegistration registration) {
    		return new NacosAutoServiceRegistration(registry,
    				autoServiceRegistrationProperties, registration);
    	}
    
    }
    

    实验结论:

    配置 效果
    不配置@EnableDiscoveryClient,不配置nacos.discovery.enable 具有服务自动注册功能,具有拉取服务信息功能
    不配置@EnableDiscoveryClient,配置nacos.discovery.enable=false 服务注册与拉取服务信息功能都不具备
    配置@EnableDiscoveryClient(autoRegister=false),配置nacos.discovery.enable=true 不具有服务注册功能,具有拉取服务信息功能
    配置@EnableDiscoveryClient(autoRegister=false),配置nacos.discovery.enable=false 服务注册与拉取服务信息功能都不具备

    最后:

    才疏学浅,难免有疏漏或者错误的地方,希望各位不吝指教

  • 相关阅读:
    中国软件外包IT公司最新排名
    DJ舞曲、音乐与爱好!
    linux论坛
    IBM P 系列小型机的控件面板功能~!(转用)
    JDBC Driver 驱动 For SQL 2008 Server /2005 /2000
    年报盘点:149家公司筹码大幅集中
    公式指标—精华
    观峰雨个人空间 2010 STOCK ADVICE !
    IntelliJ IDEA提示Cannot resolve symbol
    今天天变的好冷了~
  • 原文地址:https://www.cnblogs.com/llysc/p/14982849.html
Copyright © 2011-2022 走看看