nacos服务注册源码过程阅读

准备部分

在这里插入图片描述

这是在真正调用注册实例的方法之前,需要使用到的对象的关系图。

源码跟踪

NacosServiceRegistryAutoConfiguration类
@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(
	 //  在spring.factories中,有个自动创建的类是 NacosServiceAutoConfiguration,这个类里创建了 NacosServiceManager 对象,也就是对应这里的第一个参数
			NacosServiceManager nacosServiceManager, 
			NacosDiscoveryProperties nacosDiscoveryProperties) {   //  取的配置文件
		return new NacosServiceRegistry(nacosServiceManager, nacosDiscoveryProperties);
	}

	@Bean
	@ConditionalOnBean(AutoServiceRegistrationProperties.class)
	public NacosRegistration nacosRegistration(
			ObjectProvider<List<NacosRegistrationCustomizer>> registrationCustomizers,  // 不知道是个啥,感觉不是重点所以没看
			NacosDiscoveryProperties nacosDiscoveryProperties,  // 配置文件
			ApplicationContext context) {   // spring容器创建的
		return new NacosRegistration(registrationCustomizers.getIfAvailable(),
				nacosDiscoveryProperties, context);
	}

	@Bean
	@ConditionalOnBean(AutoServiceRegistrationProperties.class)
	这个是才是重点对象
	public NacosAutoServiceRegistration nacosAutoServiceRegistration(
			NacosServiceRegistry registry,  // 上面第一个方法创建的Bean
			AutoServiceRegistrationProperties autoServiceRegistrationProperties,    // 取的配置文件中的值
			NacosRegistration registration) {  // 上面第二个方法创建的Bean
		return new NacosAutoServiceRegistration(registry,
				autoServiceRegistrationProperties, registration);
	}

}
AbstractAutoServiceRegistration类

直接看NacosAutoServiceRegistration继承的这个抽象类

	@Override
	@SuppressWarnings("deprecation")
	//  NacosAutoServiceRegistration类有实现ApplicationListener<WebServerInitializedEvent>,所以会监听到WebServerInitializedEvent事件
	public void onApplicationEvent(WebServerInitializedEvent event) {
		bind(event);
	}


	public void bind(WebServerInitializedEvent event) {
		ApplicationContext context = event.getApplicationContext();
		if (context instanceof ConfigurableWebServerApplicationContext) {
			if ("management".equals(((ConfigurableWebServerApplicationContext) context).getServerNamespace())) {
				return;
			}
		}
		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;
		}

		if (!this.running.get()) {
		//  NacosServiceManager类中的 onInstancePreRegisteredEvent 方法上有@EventListener,会监听到这个预注册事件,具体不知道逻辑,看变量名称好像缓存		    	                  用的
			this.context.publishEvent(new InstancePreRegisteredEvent(this, getRegistration()));
			// 会调用register方法
			register();
			if (shouldRegisterManagement()) {
				registerManagement();
			}
			this.context.publishEvent(new InstanceRegisteredEvent<>(this, getConfiguration()));
			this.running.compareAndSet(false, true);
		}

	}
NacosServiceRegistry类

一直溯源register方法,会看到NacosServiceRegistry类中的register(Registration registration)方法,

@Override
	public void register(Registration registration) {

		if (StringUtils.isEmpty(registration.getServiceId())) {
			log.warn("No service to register for nacos client...");
			return;
		}
		//  这里的namingService()溯源会看到创建这个NamingService 用到了反射
		NamingService namingService = namingService();
		// serviceId 其实就是spring.application.name值
		String serviceId = registration.getServiceId();
		String group = nacosDiscoveryProperties.getGroup();
		
		// 直接new一个Instance对象
		Instance instance = getNacosInstanceFromRegistration(registration);

		try {
			namingService.registerInstance(serviceId, group, instance);
			log.info("nacos registry, {} {} {}:{} register finished", group, serviceId,
					instance.getIp(), instance.getPort());
		}
		catch (Exception e) {
			if (nacosDiscoveryProperties.isFailFast()) {
				log.error("nacos registry, {} register failed...{},", serviceId,
						registration.toString(), e);
				rethrowRuntimeException(e);
			}
			else {
				log.warn("Failfast is false. {} register failed...{},", serviceId,
						registration.toString(), e);
			}
		}
	}

创建NamingService的具体代码:

    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);
            NamingService vendorImpl = (NamingService)constructor.newInstance(properties);
            return vendorImpl;
        } catch (Throwable var4) {
            throw new NacosException(-400, var4);
        }
    }
NacosNamingService类
    public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException {
    //  这里校验的就是配置的心跳间隔和心跳超时,ip删除超时三个参数的值的大小关系,心跳间隔必须比这两个都要小
        NamingUtils.checkInstanceIsLegal(instance);
        String groupedServiceName = NamingUtils.getGroupedName(serviceName, groupName);
        //  如果是临时实例,就会开一个心跳线程,不设置事件默认应该是5s的延迟
        if (instance.isEphemeral()) {
            BeatInfo beatInfo = this.beatReactor.buildBeatInfo(groupedServiceName, instance);
            this.beatReactor.addBeatInfo(groupedServiceName, beatInfo);
        }

        this.serverProxy.registerService(groupedServiceName, groupName, instance);
    }
NamingProxy类
    public String callServer(String api, Map<String, String> params, Map<String, String> body, String curServer, String method) throws NacosException {
        long start = System.currentTimeMillis();
        long end = 0L;
        this.injectSecurityInfo(params);
        Header header = this.builderHeader();
        String url;
        if (!curServer.startsWith("https://") && !curServer.startsWith("http://")) {
            if (!IPUtil.containsPort(curServer)) {
                curServer = curServer + ":" + this.serverPort;
            }

            url = NamingHttpClientManager.getInstance().getPrefix() + curServer + api;
        } else {
            url = curServer + api;
        }

        try {
        // 这里的nacosRestTemplate 点进去溯源之后会发现 
            HttpRestResult<String> restResult = this.nacosRestTemplate.exchangeForm(url, header, Query.newInstance().initParams(params), body, method, String.class);
            end = System.currentTimeMillis();
            MetricsMonitor.getNamingRequestMonitor(method, url, String.valueOf(restResult.getCode())).observe((double)(end - start));
            if (restResult.ok()) {
                return (String)restResult.getData();
            } else if (304 == restResult.getCode()) {
                return "";
            } else {
                throw new NacosException(restResult.getCode(), restResult.getMessage());
            }
        } catch (Exception var13) {
            LogUtils.NAMING_LOGGER.error("[NA] failed to request", var13);
            throw new NacosException(500, var13);
        }
    }
// 先是在NamingProxy中显式创建NacosRestTemplate 对象
private final NacosRestTemplate nacosRestTemplate = NamingHttpClientManager.getInstance().getNacosRestTemplate();


NamingHttpClientManager类

//  这里传入的参数其实是NamingHttpClientFactory对象,并且这个对象是继承了AbstractHttpClientFactory抽象类的
    public NacosRestTemplate getNacosRestTemplate() {
        return HttpClientBeanHolder.getNacosRestTemplate(HTTP_CLIENT_FACTORY);
    }


HttpClientBeanHolder类

  public static NacosRestTemplate getNacosRestTemplate(HttpClientFactory httpClientFactory) {
        if (httpClientFactory == null) {
            throw new NullPointerException("httpClientFactory is null");
        }
        String factoryName = httpClientFactory.getClass().getName();
        NacosRestTemplate nacosRestTemplate = SINGLETON_REST.get(factoryName);
        if (nacosRestTemplate == null) {
            synchronized (SINGLETON_REST) {
                nacosRestTemplate = SINGLETON_REST.get(factoryName);
                if (nacosRestTemplate != null) {
                    return nacosRestTemplate;
                }
                //  如果SINGLETON_REST 这个集合中没有找到,会走到这个方法,会发现 参数传过来的 httpClientFactory是个接口,并且有两个实现类,分别是AbstractApacheHttpClientFactory和AbstractHttpClientFactory,因为知道入参其实就是NamingHttpClientFactory,并且继承了AbstractHttpClientFactory
                nacosRestTemplate = httpClientFactory.createNacosRestTemplate();
                SINGLETON_REST.put(factoryName, nacosRestTemplate);
            }
        }
        return nacosRestTemplate;
    }


AbstractHttpClientFactory类

        HttpClientConfig httpClientConfig = buildHttpClientConfig();
        // 这里就知道NacosRestTemplate中的HttpClientRequest属性其实是  JdkHttpClientRequest实例对象,
        final JdkHttpClientRequest clientRequest = new JdkHttpClientRequest(httpClientConfig);
        
        // enable ssl
        initTls(new BiConsumer<SSLContext, HostnameVerifier>() {
            @Override
            public void accept(SSLContext sslContext, HostnameVerifier hostnameVerifier) {
                clientRequest.setSSLContext(loadSSLContext());
                clientRequest.replaceSSLHostnameVerifier(hostnameVerifier);
            }
        }, new TlsFileWatcher.FileChangeListener() {
            @Override
            public void onChanged(String filePath) {
                clientRequest.setSSLContext(loadSSLContext());
            }
        });
        
        return new NacosRestTemplate(assignLogger(), clientRequest);
    }
NacosRestTemplate类

在上面NamingProxy中一顿点击之后,会调用到NacosRestTemplate的execute方法,如下

    private <T> HttpRestResult<T> execute(String url, String httpMethod, RequestHttpEntity requestEntity,
            Type responseType) throws Exception {
        URI uri = HttpUtils.buildUri(url, requestEntity.getQuery());
        if (logger.isDebugEnabled()) {
            logger.debug("HTTP method: {}, url: {}, body: {}", httpMethod, uri, requestEntity.getBody());
        }
        
        ResponseHandler<T> responseHandler = super.selectResponseHandler(responseType);
        HttpClientResponse response = null;
        try {
        /// 上面溯源得到的  JdkHttpClientRequest  对应的就是this.requestClient(),因为上面可以看到调用NacosRestTemplate的构造函数,传入的是JdkHttpClientRequest  
            response = this.requestClient().execute(uri, httpMethod, requestEntity);
            return responseHandler.handle(response);
        } finally {
            if (response != null) {
                response.close();
            }
        }
    }

之后就是使用HttpURLConnection实际发情请求,并且处理Response了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值