【java-nacos】注冊(cè)grpc端口至nacos

背景

公司使用nacos-discovery作為服務(wù)注冊(cè)和服務(wù)發(fā)現(xiàn),使用nacos-conf作為配置中心,通信的方式使用的是grpc,所以希望關(guān)閉http端口,使用grpc端口

技術(shù)方案

application.properties文件中關(guān)閉web配置,即spring.main.web-application-type設(shè)置為 none,并且添加配置spring.cloud.nacos.discovery.port=XXX

一. 出現(xiàn)問(wèn)題

啟動(dòng)服務(wù)時(shí)一切正常,但是發(fā)現(xiàn)服務(wù)不往nacos上注冊(cè),也沒(méi)有出現(xiàn)任何異常提示,直接調(diào)用grpc端口可以正常通信。

二. nacos注冊(cè)原理和時(shí)機(jī)

nacos-client主要是通過(guò)com.alibaba.cloud.nacos.registry.NacosAutoServiceRegistration管理注冊(cè)行為,實(shí)際上就是向nacos-server上發(fā)送一個(gè)POST請(qǐng)求

該類繼承自org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration,這個(gè)類是spirng-cloud對(duì)于服務(wù)注冊(cè)的一個(gè)通用抽象,其中一個(gè)關(guān)鍵的接口是ApplicationListener<WebServerInitializedEvent>

換句話說(shuō),服務(wù)注冊(cè)到nacos上的時(shí)機(jī)是收到spirng中web組件成功實(shí)例化后發(fā)布的事件后。

那么這就合理了,將web端口關(guān)閉后,spring不會(huì)去初始化web相關(guān)實(shí)例,也就不會(huì)發(fā)布web實(shí)例初始化成功的事件,所以nacos不會(huì)執(zhí)行注冊(cè)的東西,而其他操作毫無(wú)影響

三. 解決方案
NacosServiceRegistry是nacos注冊(cè)到spring當(dāng)中的bean,其中的register()方法也是底層最終實(shí)現(xiàn)注冊(cè)動(dòng)作的類,所以我們可以通過(guò)將該bean注入到我們自己的服務(wù)中,并通過(guò)手動(dòng)調(diào)用的方式注冊(cè)到nacos-server上

四. 其他
另有同學(xué)說(shuō),有沒(méi)有可能grpc server正在實(shí)例化,端口就已經(jīng)注冊(cè)到nacos上了,會(huì)不會(huì)造成短暫的不可用?
spring啟動(dòng)的核心邏輯在org.springframework.context.support.AbstractApplicationContext#refresh方法中,如下

...
            // Prepare this context for refreshing.
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);

            
            // Allows post-processing of the bean factory in context subclasses.
            postProcessBeanFactory(beanFactory);

            StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
            // Invoke factory processors registered as beans in the context.
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            registerBeanPostProcessors(beanFactory);
            beanPostProcess.end();

            // Initialize message source for this context.
            initMessageSource();

            // Initialize event multicaster for this context.
            initApplicationEventMulticaster();

            // Initialize other special beans in specific context subclasses.
            onRefresh();

            // Check for listener beans and register them.
            registerListeners();

            // Instantiate all remaining (non-lazy-init) singletons.
            finishBeanFactoryInitialization(beanFactory);

            // Last step: publish corresponding event.
            finishRefresh();
···     

finishRefresh方法如下

protected void finishRefresh() {
        // Clear context-level resource caches (such as ASM metadata from scanning).
        clearResourceCaches();

        // Initialize lifecycle processor for this context.
        initLifecycleProcessor();

        // Propagate refresh to lifecycle processor first.
        getLifecycleProcessor().onRefresh();

        // Publish the final event.
        publishEvent(new ContextRefreshedEvent(this));

        // Participate in LiveBeansView MBean, if active.
        if (!IN_NATIVE_IMAGE) {
            LiveBeansView.registerApplicationContext(this);
        }
    }

可以很清楚的看到,只有當(dāng)所有的bean都實(shí)例化完成之后才會(huì)輪到finishRefresh,而發(fā)布web事件是在getLifecycleProcessor().onRefresh();,所以只要grpc-server是一個(gè)spring的bean,那注冊(cè)到nacos上的端口就一定可用

結(jié)論

spring-cloud環(huán)境下,nacos的服務(wù)注冊(cè)是依賴于spring的事件發(fā)布的,我們自己的服務(wù)也可以利用事件發(fā)布在spring初始化后做一些相應(yīng)的操作

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容