Nacos - 客戶端註冊

大軍發表於2021-01-04

Nacos - 啟動中提到了註冊的入口,這裡就講一下注冊的細節。
Tomcat啟動成功後,會呼叫AbstractAutoServiceRegistration的onApplicationEvent方法,他會繼續呼叫AbstractAutoServiceRegistration#bind。

AbstractAutoServiceRegistration#bind

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();
}

AbstractAutoServiceRegistration#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()) {
        // 釋出InstancePreRegisteredEvent事件
        this.context.publishEvent(
                new InstancePreRegisteredEvent(this, getRegistration()));
        // 註冊
        register();
        if (shouldRegisterManagement()) {
            // 註冊registerManagement
            registerManagement();
        }
        // 釋出InstanceRegisteredEvent事件
        this.context.publishEvent(
                new InstanceRegisteredEvent<>(this, getConfiguration()));
        // 設定狀態為啟動
        this.running.compareAndSet(false, true);
    }

}

NacosAutoServiceRegistration#register

protected void register() {
    if (!this.registration.getNacosDiscoveryProperties().isRegisterEnabled()) {
        log.debug("Registration disabled.");
        return;
    }
    // 小於0重新設定埠
    if (this.registration.getPort() < 0) {
        this.registration.setPort(getPort().get());
    }
    super.register();
}

AbstractAutoServiceRegistration#register

registration的注入在啟動的時候已經說過了。

protected void register() {
    this.serviceRegistry.register(getRegistration());
}

NacosServiceRegistry#register

封裝好Instance後,呼叫NacosNamingService的registerInstance方法註冊。Nacos - NacosNamingService初始化以及幾個其他定時任務已經講過了。

public void register(Registration registration) {

    if (StringUtils.isEmpty(registration.getServiceId())) {
        log.warn("No service to register for nacos client...");
        return;
    }
    // 獲取NacosNamingService
    NamingService namingService = namingService();
    // 獲取serviceId
    String serviceId = registration.getServiceId();
    String group = nacosDiscoveryProperties.getGroup();
    // 獲取Instance,一些資訊從registration讀取,一些從nacosDiscoveryProperties讀取
    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) {
        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);
    }
}

NacosNamingService#registerInstance

封裝心跳資訊、開啟定時任務續約以及呼叫serverProxy註冊,這個url是/nacos/v1/ns/instance。

public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException {
    String groupedServiceName = NamingUtils.getGroupedName(serviceName, groupName);
    if (instance.isEphemeral()) {
        // 封裝心跳資訊
        BeatInfo beatInfo = beatReactor.buildBeatInfo(groupedServiceName, instance);
        // 開啟定時任務續約
        beatReactor.addBeatInfo(groupedServiceName, beatInfo);
    }
    serverProxy.registerService(groupedServiceName, groupName, instance);
}

相關文章