nacos服务注册与发现

https://blog.csdn.net/yaomingyang/article/details/110879101
https://www.cnblogs.com/crazymakercircle/p/14231815.html
https://www.cnblogs.com/llysc/p/14982849.html
https://blog.csdn.net/qq_40125268/article/details/131478039


### ----------------------------------------------------------------------------------------------nacos服务注册与发现
nacos实现动态发现和注册的原理,nacos 1.x之间的数据同步靠http协议同步,2.x版本后改成distro协议来同步数据。
注册与发现是通过订阅机制来实现的。客户端通过订阅注册中心,注册中心则会返回当前注册在注册中心的所有的实例,
返回的数据就包含了其他客户端的ip和端口,则可以通过ip和端口对其他客户端服务进行访问和调用。

### nacos服务注册


理解@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的类,那就打开看一下:
此类是实现自动注册的入口,具体的逻辑在由注册中心实现(如Nacos\Eureka...)


@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(AutoServiceRegistrationProperties.class)
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled",                属性为true时,此配置类会被加载
        matchIfMissing = true)
public class AutoServiceRegistrationConfiguration {
                                                                        配置类有两个作用,
                                                                        第一将AutoServiceRegistrationProperties属性配置类注入IOC容器,
                                                                        其二只有在spring.cloud.service-registry.auto-registration.enabled为true时才将配置类注入IOC容器,
                                                                        默认就为true;

}
当**.registration.enabled=spring-cloud-commons.jar包内的spring-configuration-metadata.json定义了此属性默认为true
即: 不配置@EnableDiscoveryClient或者配置@EnableDiscoveryClient设置autoRegister为true时AutoServiceRegistrationConfiguration会被加载,
    当@EnableDiscoveryClient设置autoRegister属性为false时,此配置类AutoServiceRegistrationConfiguration不会被加载

既然@EnableDiscoveryClient注解不配置AutoServiceRegistrationConfiguration一样可以注入到IOC容器,那么说明肯定是有其他的地方有注入,
    看下spring.factories配置文件中的自动化配置有一个 AutoServiceRegistrationAutoConfiguration 自动化配置类,再看下其源码:

@Configuration(proxyBeanMethods = false)
@Import(AutoServiceRegistrationConfiguration.class)
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)
public class AutoServiceRegistrationAutoConfiguration implements InitializingBean {
}
看到上面有一个@Import将AutoServiceRegistrationConfiguration配置类注入IOC容器,
这里就说明了如果EnableDiscoveryClientImportSelector类没有将配置类注入IOC容器,那么此处就会将其注入。
    
    
由于spring boot默认启用了@EnableAutoConfiguration,所以nacos-discovery包的spring.factories文件中会加载;
找到nacos的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,\          nacos服务注册自动配置类。主要注册NacosAutoServiceRegistration类的bean实例
  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


 


那服务注册功能呢? NacosServiceRegistryAutoConfiguration
服务自动注册逻辑:

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties

@ConditionalOnNacosDiscoveryEnabled                                                                             确保spring.cloud.nacos.discovery.enabled为true
                                                                                                                (开启nacos的服务注册与发现功能)
                                                                                                                
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled",        
        matchIfMissing = true)                                                                                   默认为true,使用@EnableDiscoveryClient注解配置autoRegister为false时,
                                                                                                                 此属性值为false即: 此类不被加载,即: 服务不具备自动注册功能
@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);
    }

}

-> new NacosAutoServiceRegistration()                                                   该类的构造方法,其实例化通过其父类AbstractAutoServiceRegistration的构造方法实现
-> new AbstractAutoServiceRegistration()                                                该类实现了ApplicationListener接口,这个接口可以监听容器中发布WebServerInitializedEvent事件,
                                                                                        这个事件会在应用上下文刷新后和WebServer已经准备好之后被发布,
                                                                                        然后触发onApplicationEvent,执行bind()方法。
...
-> AbstractAutoServiceRegistration.onApplicationEvent()
    register()
-> AbstractAutoServiceRegistration.register()
    this.serviceRegistry.register(getRegistration())
-> NacosServiceRegistry.register()
    namingService.registerInstance(serviceId, group, instance);
-> NacosNamingService.registerInstance()
    clientProxy.registerService(serviceName, groupName, instance);
-> NamingClientProxy.registerService()                                               有三种实现:NamingGrpcClientProxy NamingClientProxyDelegate NamingHttpClientProxy    
注册服务的逻辑中包含如下几个步骤:

1.redoService是去添加redo日志,实际上通过registeredInstances 的map结构来存储redo日志
2.doRegisterService是真正发起注册的逻辑,其中requestToServer 方法就是发送gRpc协议请求,
  去完成注册,然后instanceRegistered方法主要是标记当前服务已经完成注册逻辑。
 
    
-> NamingGrpcClientProxy.registerService()  
    redoService.cacheInstanceForRedo(serviceName, groupName, instance);
    doRegisterService(serviceName, groupName, instance);
-> NamingGrpcClientProxy.doRegisterService()

    public void doRegisterService(String serviceName, String groupName, Instance instance) throws NacosException {
        InstanceRequest request = new InstanceRequest(namespaceId, serviceName, groupName,
                NamingRemoteConstants.REGISTER_INSTANCE, instance);
        requestToServer(request, Response.class);                                         实例注册
        redoService.instanceRegistered(serviceName, groupName);                           实例注册成功后,会把redo日志中实例标记成注册成功                          
    }


    
注入NacosDiscoveryAutoConfiguration

    新建NacosDiscoveryProperties服务发现属性和命名服务
    新建NacosServiceDiscovery通过NacosDiscoveryProperties的NamingService获取信息,将Instance封装成ServiceInstance。


注入NacosDiscoveryClientConfiguration获取服务信息用

    新建NacosDiscoveryClient
    新建GatewayLocatorHeartBeatPublisher
    新建NacosWatch
 
NacosDiscoveryEndpointAutoConfiguration监控相关
    新建NacosDiscoveryEndpoint
    新建NacosDiscoveryHealthIndicator健康检查


  
### 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,服务就具有拉取注册中心信息的功能

  
  
 


 

  • 7
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值