SpringBoot部署到外部Tomcat無(wú)法注冊(cè)到Nacos服務(wù)端的解決思路
事情經(jīng)過(guò)
近期做一個(gè)項(xiàng)目投標(biāo)演示(POC)環(huán)境支持,需要集成Nacos服務(wù)端。考慮到現(xiàn)有項(xiàng)目中已經(jīng)有了Nacos相關(guān)依賴,那還不簡(jiǎn)單?新建個(gè)服務(wù)端,配置幾下重啟不就搞定了嗎?然而事情遠(yuǎn)沒(méi)有想得這么簡(jiǎn)單。同樣的代碼在我本地IDE里運(yùn)行就能注冊(cè)成功,在演示環(huán)境 Tomcat+War 部署就不行了。
經(jīng)過(guò)遠(yuǎn)程Debug代碼,發(fā)現(xiàn)Nacos客戶端的線程都有啟動(dòng),卻沒(méi)有注冊(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
大致是說(shuō)只有當(dāng) Spring Boot 啟動(dòng)內(nèi)嵌 Tomcat 成功后,才會(huì)發(fā)布 WebServerInitializedEvent
事件。而Nacos客戶端在等這個(gè)事件出現(xiàn)才會(huì)向服務(wù)端注冊(cè)自己。又因部署在外部Tomcat中就不會(huì)初始化內(nèi)嵌Tomcat,也就沒(méi)觸發(fā)這個(gè)事件。
所以解決方法就是將Nacos等事件的部分代碼調(diào)用下,讓他們啟動(dòng)注冊(cè)。
Nacos的自動(dòng)注冊(cè)類是 NacosAutoServiceRegistration
,它繼承Spring Cloud的AbstractAutoServiceRegistration
,在AbstractAutoServiceRegistration
等的 bind(WebServerInitializedEvent)
方法監(jiān)聽(tīng)事件,設(shè)置端口號(hào)并啟動(dòng)注冊(cè)。這里邊 this.port
是從事件中獲取的,需要我們自行獲取。
設(shè)置port的位置可見(jiàn),是從org.springframework.cloud.client.serviceregistry.Registration
中取到的,給它設(shè)置一下就可以了。
解決辦法
我寫了一個(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); } }
經(jīng)過(guò)我這一波操作問(wèn)題終于解決了。我是Hellxz,不在進(jìn)坑就在爬坑的路上。
到此這篇關(guān)于SpringBoot部署到外部Tomcat無(wú)法注冊(cè)到Nacos服務(wù)端的文章就介紹到這了,更多相關(guān)SpringBoot無(wú)法注冊(cè)到Nacos服務(wù)端內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot使用JUL實(shí)現(xiàn)日志記錄功能
在SpringBoot中,我們可以使用多種日志框架進(jìn)行日志記錄,其中,JUL(Java Util Logging)是Java平臺(tái)自帶的日志框架,它提供了簡(jiǎn)單的 API 和配置,可以輕松地進(jìn)行日志記錄,本文將介紹如何在 SpringBoot中使用JUL進(jìn)行日志記錄,并提供示例代碼2023-06-06Java8中Stream?API的peek()方法詳解及需要注意的坑
這篇文章主要給大家介紹了關(guān)于Java8中Stream?API的peek()方法詳解及需要注意的坑,Java 中的 peek 方法是 Java 8 中的 Stream API 中的一個(gè)方法,它屬于中間操作,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-06-06JAVA實(shí)現(xiàn)Date日期加一天具體方法
這篇文章主要給大家介紹了關(guān)于JAVA實(shí)現(xiàn)Date日期加一天的相關(guān)資料,因?yàn)樵陧?xiàng)目中遇到了需要將日期進(jìn)行加減一些天數(shù)的操作,文中給出了簡(jiǎn)單的代碼示例,需要的朋友可以參考下2023-07-07如何用Maven開(kāi)發(fā)Spring?Boot項(xiàng)目詳解
SpringBoot是一個(gè)集成Spring框架優(yōu)點(diǎn)的開(kāi)源后臺(tái)開(kāi)發(fā)框架,自動(dòng)化配置和內(nèi)嵌容器等特性減少了配置工作量,使得開(kāi)發(fā)者可以更加專注于業(yè)務(wù)邏輯,這篇文章主要介紹了如何用Maven開(kāi)發(fā)Spring?Boot項(xiàng)目,需要的朋友可以參考下2024-09-09SpringMVC中RequestContextHolder獲取請(qǐng)求信息的方法
這篇文章主要介紹了SpringMVC中RequestContextHolder獲取請(qǐng)求信息的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04Springboot結(jié)合Flowable實(shí)現(xiàn)工作流開(kāi)發(fā)
本文主要介紹了Springboot結(jié)合Flowable實(shí)現(xiàn)工作流開(kāi)發(fā),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01