溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

SpringBoot部署到外部Tomcat無法注冊(cè)到Nacos服務(wù)端如何解決

發(fā)布時(shí)間:2023-03-17 09:43:40 來源:億速云 閱讀:114 作者:iii 欄目:開發(fā)技術(shù)

本文小編為大家詳細(xì)介紹“SpringBoot部署到外部Tomcat無法注冊(cè)到Nacos服務(wù)端如何解決”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“SpringBoot部署到外部Tomcat無法注冊(cè)到Nacos服務(wù)端如何解決”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學(xué)習(xí)新知識(shí)吧。

事情經(jīng)過

近期做一個(gè)項(xiàng)目投標(biāo)演示(POC)環(huán)境支持,需要集成Nacos服務(wù)端??紤]到現(xiàn)有項(xiàng)目中已經(jīng)有了Nacos相關(guān)依賴,那還不簡單?新建個(gè)服務(wù)端,配置幾下重啟不就搞定了嗎?然而事情遠(yuǎn)沒有想得這么簡單。同樣的代碼在我本地IDE里運(yùn)行就能注冊(cè)成功,在演示環(huán)境 Tomcat+War 部署就不行了。

經(jīng)過遠(yuǎn)程Debug代碼,發(fā)現(xiàn)Nacos客戶端的線程都有啟動(dòng),卻沒有注冊(cè)成功。

思路

想到可能與Tomcat部署模式有關(guān)系,就去查了官方issue和StackOverFlow

The event is published as part of Spring Boot starting the embedded Tomcat instance. If you're deploying to an external container, there's no embedded container to start and, therefore, no event is published. – Andy Wilkinson

大致是說只有當(dāng) Spring Boot 啟動(dòng)內(nèi)嵌 Tomcat 成功后,才會(huì)發(fā)布 WebServerInitializedEvent 事件。而Nacos客戶端在等這個(gè)事件出現(xiàn)才會(huì)向服務(wù)端注冊(cè)自己。又因部署在外部Tomcat中就不會(huì)初始化內(nèi)嵌Tomcat,也就沒觸發(fā)這個(gè)事件。

所以解決方法就是將Nacos等事件的部分代碼調(diào)用下,讓他們啟動(dòng)注冊(cè)。

Nacos的自動(dòng)注冊(cè)類是 NacosAutoServiceRegistration,它繼承Spring Cloud的AbstractAutoServiceRegistration,在AbstractAutoServiceRegistration等的 bind(WebServerInitializedEvent)方法監(jiān)聽事件,設(shè)置端口號(hào)并啟動(dòng)注冊(cè)。這里邊 this.port 是從事件中獲取的,需要我們自行獲取。

SpringBoot部署到外部Tomcat無法注冊(cè)到Nacos服務(wù)端如何解決

設(shè)置port的位置可見,是從org.springframework.cloud.client.serviceregistry.Registration中取到的,給它設(shè)置一下就可以了。

SpringBoot部署到外部Tomcat無法注冊(cè)到Nacos服務(wù)端如何解決

解決辦法

我寫了一個(gè)完整的配置類放到了該ISSUE下邊,這里直接貼在下邊。

import java.lang.management.ManagementFactory;
import java.util.Set;
 
import javax.annotation.PostConstruct;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.Query;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
 
import com.alibaba.cloud.nacos.registry.NacosAutoServiceRegistration;
import com.alibaba.cloud.nacos.registry.NacosRegistration;
 
@Configuration
public class NacosWarDeployConfig {
    private static final Logger logger = LoggerFactory.getLogger(NacosWarDeployConfig.class);
 
    @Autowired
    private Environment env;
    @Autowired
    private NacosRegistration registration;
    @Autowired
    private NacosAutoServiceRegistration nacosAutoServiceRegistration;
 
    @PostConstruct
    public void nacosServerRegister() {
        if (registration != null) {
            registration.setPort(getTomcatPort());
            nacosAutoServiceRegistration.start();
        }
    }
 
    public int getTomcatPort() {
        try {
            return getProvideTomcatPort();
        } catch (Exception e) {
            logger.warn("obtain provide tomcat port failed, fallback to embeded tomcat port.");
        }
        return getEmbeddedTomcatPort();
    }
 
    private int getProvideTomcatPort() throws MalformedObjectNameException, NullPointerException {
        MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();
        Set<ObjectName> objectNames = beanServer.queryNames(new ObjectName("*:type=Connector,*"),
                Query.match(Query.attr("protocol"), Query.value("HTTP/1.1")));
        String port = objectNames.iterator().next().getKeyProperty("port");
        return Integer.valueOf(port);
    }
 
    private int getEmbeddedTomcatPort() {
        return env.getProperty("server.port", Integer.class, 8080);
    }
 
}

讀到這里,這篇“SpringBoot部署到外部Tomcat無法注冊(cè)到Nacos服務(wù)端如何解決”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI