nacos-登録ソースプロファイル


一.pom依存に基づいて登録主クラスを見つける
  • 自動アセンブリクラスを見つけてnacosを使用して登録し、pomにnacos-discovery依存
  • を追加します.
    
    <dependency>
        <groupId>com.alibaba.cloudgroupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
    dependency>
    
  • 依存の中でこのjarパッケージを見つけて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
    
    
  • Nacosサービス登録自動アセンブリクラスを見つけました-->Nacos ServiceRegistryAutoConfiguration、次にこのクラスから
  • を登録します.
    二.ソース解析NacosServiceRegistryAutoConfiguration
    大胆な推測:ソースコードを見る前に大まかに推測すると、登録されたjarである以上、彼の業務ロジックは少なくとも:第一歩:springIOCの初期化後にdubbo登録のように、onApplicationEventが登録をトリガーし、第二歩:配置されたymlパラメータに基づいてnacos登録センターに登録する.nacos登録センターにもサービス情報を残します.これにより、他のサービスが知る、呼び出される.仲介役に相当する.
    @Configuration(proxyBeanMethods = false)
    @EnableConfigurationProperties
    @ConditionalOnNacosDiscoveryEnabled
    @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);
    	}
    
    }
    
  • NacosRegistration
  • public class NacosRegistration implements Registration, ServiceInstance {
         
    	...
    
    	// @PostConstruct                               yml      metadata set
    	@PostConstruct
    	public void init() {
         
    
    		Map<String, String> metadata = nacosDiscoveryProperties.getMetadata();
    		Environment env = context.getEnvironment();
    
    		String endpointBasePath = env.getProperty(MANAGEMENT_ENDPOINT_BASE_PATH);
    		if (!StringUtils.isEmpty(endpointBasePath)) {
         
    			metadata.put(MANAGEMENT_ENDPOINT_BASE_PATH, endpointBasePath);
    		}
    
    		Integer managementPort = ManagementServerPortUtils.getPort(context);
    		if (null != managementPort) {
         
    			metadata.put(MANAGEMENT_PORT, managementPort.toString());
    			String contextPath = env
    					.getProperty("management.server.servlet.context-path");
    			String address = env.getProperty("management.server.address");
    			if (!StringUtils.isEmpty(contextPath)) {
         
    				metadata.put(MANAGEMENT_CONTEXT_PATH, contextPath);
    			}
    			if (!StringUtils.isEmpty(address)) {
         
    				metadata.put(MANAGEMENT_ADDRESS, address);
    			}
    		}
    
    		if (null != nacosDiscoveryProperties.getHeartBeatInterval()) {
         
    			metadata.put(PreservedMetadataKeys.HEART_BEAT_INTERVAL,
    					nacosDiscoveryProperties.getHeartBeatInterval().toString());
    		}
    		if (null != nacosDiscoveryProperties.getHeartBeatTimeout()) {
         
    			metadata.put(PreservedMetadataKeys.HEART_BEAT_TIMEOUT,
    					nacosDiscoveryProperties.getHeartBeatTimeout().toString());
    		}
    		if (null != nacosDiscoveryProperties.getIpDeleteTimeout()) {
         
    			metadata.put(PreservedMetadataKeys.IP_DELETE_TIMEOUT,
    					nacosDiscoveryProperties.getIpDeleteTimeout().toString());
    		}
    		customize(registrationCustomizers, this);
    	}
    	...
    }
    
  • AbstractAutoServiceRegistration
  • public abstract class AbstractAutoServiceRegistration<R extends Registration>
    		implements AutoServiceRegistration, ApplicationContextAware,
    		ApplicationListener<WebServerInitializedEvent> {
         
    	...
    	
    	//             spring          
    	@Override
    	@SuppressWarnings("deprecation")
    	public void onApplicationEvent(WebServerInitializedEvent event) {
         
    		bind(event);
    	}
    
    	@Deprecated
    	public void bind(WebServerInitializedEvent event) {
         
    		ApplicationContext context = event.getApplicationContext();
    		if (context instanceof ConfigurableWebServerApplicationContext) {
         
    			if ("management".equals(((ConfigurableWebServerApplicationContext) context)
    					.getServerNamespace())) {
         
    				return;
    			}
    		}
    		// CAS
    		this.port.compareAndSet(0, event.getWebServer().getPort());
    		this.start();
    	}
    	
    	...
    	
    	//         
    	public void start() {
         
    		if (!isEnabled()) {
         
    			if (logger.isDebugEnabled()) {
         
    				logger.debug("Discovery Lifecycle disabled. Not starting");
    			}
    			return;
    		}
    
    		// only initialize if nonSecurePort is greater than 0 and it isn't already running
    		// because of containerPortInitializer below
    		if (!this.running.get()) {
         
    			this.context.publishEvent(
    					new InstancePreRegisteredEvent(this, getRegistration()));
    			//   register        @Bean NacosServiceRegistry   register  
    			//     NacosServiceRegistry register    
    			register();
    			if (shouldRegisterManagement()) {
         
    				registerManagement();
    			}
    			this.context.publishEvent(
    					new InstanceRegisteredEvent<>(this, getConfiguration()));
    			this.running.compareAndSet(false, true);
    		}
    
    	}
    
    	...
    }
    
  • NacosServiceRegistry
  • public class NacosServiceRegistry implements ServiceRegistry<Registration> {
         
    	...
    
    	@Override
    	public void register(Registration registration) {
         
    
    		if (StringUtils.isEmpty(registration.getServiceId())) {
         
    			log.warn("No service to register for nacos client...");
    			return;
    		}
    		// 1.   NamingService      service    
    		NamingService namingService = namingService();
    		String serviceId = registration.getServiceId();
    		String group = nacosDiscoveryProperties.getGroup();
    
    		Instance instance = getNacosInstanceFromRegistration(registration);
    
    		try {
         
    			//         namingService       http     nacos    
    			namingService.registerInstance(serviceId, group, instance);
    			log.info("nacos registry, {} {} {}:{} register finished", group, serviceId,
    					instance.getIp(), instance.getPort());
    		}
    		catch (Exception e) {
         
    			log.error("nacos registry, {} register failed...{},", serviceId,
    					registration.toString(), e);
    			// rethrow a RuntimeException if the registration is failed.
    			// issue : https://github.com/alibaba/spring-cloud-alibaba/issues/1132
    			rethrowRuntimeException(e);
    		}
    	}
    
    	...
    
    	// 2.  nacosServiceManager   namingService      nacosServiceManager   
    	private NamingService namingService() {
         
    		return nacosServiceManager
    				.getNamingService(nacosDiscoveryProperties.getNacosProperties());
    	}
    }
    
  • NacosServiceManager
  • public class NacosServiceManager {
         
    	...
    
    	public NamingService getNamingService(Properties properties) {
         
    		if (Objects.isNull(this.namingService)) {
         
    			// 1.       
    			buildNamingService(properties);
    		}
    		return namingService;
    	}
    	...
    
    	private NamingService buildNamingService(Properties properties) {
         
    		if (Objects.isNull(namingService)) {
         
    			// sync         build
    			synchronized (NacosServiceManager.class) {
         
    				if (Objects.isNull(namingService)) {
         
    					namingService = createNewNamingService(properties);
    				}
    			}
    		}
    		return namingService;
    	}
    	...
    	
    	private NamingService createNewNamingService(Properties properties) {
         
    		try {
         
    			// 2.     api   , NamingFactory createNamingService  
    			return createNamingService(properties);
    		}
    		catch (NacosException e) {
         
    			throw new RuntimeException(e);
    		}
    	}
    
    	...
    }
    
  • NamingFactory
  • public class NamingFactory{
         
    	...
    	
    	public static NamingService createNamingService(Properties properties) throws NacosException {
         
            try {
         
                Class<?> driverImplClass = Class.forName("com.alibaba.nacos.client.naming.NacosNamingService");
                Constructor constructor = driverImplClass.getConstructor(Properties.class);
                //        NaocsNamingService
                NamingService vendorImpl = (NamingService) constructor.newInstance(properties);
                return vendorImpl;
            } catch (Throwable e) {
         
                throw new NacosException(NacosException.CLIENT_INVALID_PARAM, e);
            }
        }
    }
    
  • NaocsNamingService
  • public class NaocsNamingService{
         
    	...
    
    	@Override
        public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException {
         
        	//         
            NamingUtils.checkInstanceIsLegal(instance);
            String groupedServiceName = NamingUtils.getGroupedName(serviceName, groupName);
            //          AP   
            // nacos  CAP          AP              CP          
            if (instance.isEphemeral()) {
         
            	//       
                BeatInfo beatInfo = beatReactor.buildBeatInfo(groupedServiceName, instance);
                //    ScheduledThreadPoolExecutor        
                beatReactor.addBeatInfo(groupedServiceName, beatInfo);
            }
            // proxy          NamingProxy 
            serverProxy.registerService(groupedServiceName, groupName, instance);
        }
    	...
    }
    
  • NamingProxy
  • public class NamingProxy{
         
    	...
    
    	public void registerService(String serviceName, String groupName, Instance instance) throws NacosException {
         
            
            NAMING_LOGGER.info("[REGISTER-SERVICE] {} registering service {} with instance: {}", namespaceId, serviceName,
                    instance);
            
            final Map<String, String> params = new HashMap<String, String>(16);
            params.put(CommonParams.NAMESPACE_ID, namespaceId);
            params.put(CommonParams.SERVICE_NAME, serviceName);
            params.put(CommonParams.GROUP_NAME, groupName);
            params.put(CommonParams.CLUSTER_NAME, instance.getClusterName());
            params.put("ip", instance.getIp());
            params.put("port", String.valueOf(instance.getPort()));
            params.put("weight", String.valueOf(instance.getWeight()));
            params.put("enable", String.valueOf(instance.isEnabled()));
            params.put("healthy", String.valueOf(instance.isHealthy()));
            params.put("ephemeral", String.valueOf(instance.isEphemeral()));
            params.put("metadata", JacksonUtils.toJson(instance.getMetadata()));
            
            // UtilAndComs.nacosUrlInstance        
            // public static String nacosUrlInstance = nacosUrlBase + "/instance";
    		// nacosTemplate http     nacos       api
    		//      nacos       
            reqApi(UtilAndComs.nacosUrlInstance, params, HttpMethod.POST);
            
        }
    	
    	...
    }
    

    PS:ここではclientの登録ロジックを紹介しただけで、nacos serverは主に対外的にapiを提供して登録とインスタンス検索を実現しています.公式サイト:https://nacos.io/en-us/docs/open-api.html