SpringBoot部署到外部Tomcat無法注冊到Nacos服務(wù)端的解決思路
事情經(jīng)過
近期做一個項目投標(biāo)演示(POC)環(huán)境支持,需要集成Nacos服務(wù)端??紤]到現(xiàn)有項目中已經(jīng)有了Nacos相關(guān)依賴,那還不簡單?新建個服務(wù)端,配置幾下重啟不就搞定了嗎?然而事情遠(yuǎn)沒有想得這么簡單。同樣的代碼在我本地IDE里運行就能注冊成功,在演示環(huán)境 Tomcat+War 部署就不行了。
經(jīng)過遠(yuǎn)程Debug代碼,發(fā)現(xiàn)Nacos客戶端的線程都有啟動,卻沒有注冊成功。
思路
想到可能與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 啟動內(nèi)嵌 Tomcat 成功后,才會發(fā)布 WebServerInitializedEvent 事件。而Nacos客戶端在等這個事件出現(xiàn)才會向服務(wù)端注冊自己。又因部署在外部Tomcat中就不會初始化內(nèi)嵌Tomcat,也就沒觸發(fā)這個事件。
所以解決方法就是將Nacos等事件的部分代碼調(diào)用下,讓他們啟動注冊。
Nacos的自動注冊類是 NacosAutoServiceRegistration,它繼承Spring Cloud的AbstractAutoServiceRegistration,在AbstractAutoServiceRegistration等的 bind(WebServerInitializedEvent)方法監(jiān)聽事件,設(shè)置端口號并啟動注冊。這里邊 this.port 是從事件中獲取的,需要我們自行獲取。

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

解決辦法
我寫了一個完整的配置類放到了該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)過我這一波操作問題終于解決了。我是Hellxz,不在進(jìn)坑就在爬坑的路上。
到此這篇關(guān)于SpringBoot部署到外部Tomcat無法注冊到Nacos服務(wù)端的文章就介紹到這了,更多相關(guān)SpringBoot無法注冊到Nacos服務(wù)端內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot使用@Cacheable出現(xiàn)預(yù)覽工具亂碼的解決方法
直接使用注解進(jìn)行緩存數(shù)據(jù),我們再使用工具去預(yù)覽存儲的數(shù)據(jù)時發(fā)現(xiàn)是亂碼,這是由于默認(rèn)序列化的問題,所以接下來將給大家介紹一下SpringBoot使用@Cacheable出現(xiàn)預(yù)覽工具亂碼的解決方法,需要的朋友可以參考下2023-10-10
SpringBoot整合Druid實現(xiàn)數(shù)據(jù)庫連接池和監(jiān)控
Druid是Java語言中使用的比較多的數(shù)據(jù)庫連接池。Druid還提供了強大的監(jiān)控和擴展功能。面將介紹SpringBoot整合Druid實現(xiàn)數(shù)據(jù)庫連接池和監(jiān)控功能,感興趣的可以了解一下2021-08-08
Java利用策略模式實現(xiàn)條件判斷,告別if else
策略模式定義了一系列算法,并且將每個算法封裝起來,使得他們可以相互替換,而且算法的變化不會影響使用算法的客戶端。本文將通過案例講解如何利用Java的策略模式實現(xiàn)條件判斷,告別if----else條件硬編碼,需要的可以參考一下2022-02-02
利用Jackson實現(xiàn)數(shù)據(jù)脫敏的示例詳解
在我們的企業(yè)項目中,為了保護(hù)用戶隱私,數(shù)據(jù)脫敏成了必不可少的操作,那么我們怎么優(yōu)雅的利用Jackson實現(xiàn)數(shù)據(jù)脫敏呢,本文就來和大家詳細(xì)聊聊,希望對大家有所幫助2023-05-05
解決運行jar包出錯:ClassNotFoundException問題
這篇文章主要介紹了解決運行jar包出錯:ClassNotFoundException問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12
Java CharacterEncodingFilter案例詳解
這篇文章主要介紹了Java CharacterEncodingFilter案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08

