Heim >Java >javaLernprogramm >So lösen Sie das Problem, wenn SpringBoot auf einem externen Tomcat bereitgestellt wird und nicht beim Nacos-Server registriert werden kann
Vor Kurzem führe ich eine POC-Umgebungsunterstützung (Project Bidding Demonstration) durch, die in den Nacos-Server integriert werden muss. Ist das nicht einfach, wenn man bedenkt, dass bestehende Projekte bereits Nacos-bezogene Abhängigkeiten aufweisen? Erstellen Sie einen neuen Server, konfigurieren Sie ihn und starten Sie ihn ein paar Mal neu, oder? Allerdings sind die Dinge bei weitem nicht so einfach wie gedacht. Derselbe Code kann erfolgreich registriert werden, wenn er in meiner lokalen IDE ausgeführt wird, kann jedoch nicht in der Demoumgebung Tomcat+War bereitgestellt werden.
Nach dem Remote-Debuggen des Codes wurde festgestellt, dass die Threads des Nacos-Clients gestartet wurden, die Registrierung jedoch nicht erfolgreich war.
Da ich dachte, dass es mit dem Tomcat-Bereitstellungsmodus zusammenhängen könnte, habe ich das offizielle Problem und StackOverFlow überprüft.
Die Veranstaltung wird als Teil veröffentlicht Wenn Sie die eingebettete Tomcat-Instanz starten, gibt es keinen eingebetteten Container, der gestartet werden muss, und daher wird grob gesagt kein Ereignis veröffentlicht wenn Spring Das WebServerInitializedEvent
-Ereignis wird erst freigegeben, nachdem Boot den eingebetteten Tomcat erfolgreich gestartet hat. Der Nacos-Client wartet auf das Eintreten dieses Ereignisses, bevor er sich beim Server registriert. Da es im externen Tomcat bereitgestellt wird, wird das eingebettete Tomcat nicht initialisiert, sodass dieses Ereignis nicht ausgelöst wird.
Die Lösung besteht also darin, einige Veranstaltungscodes wie Nacos anzurufen und sie mit der Registrierung beginnen zu lassen. WebServerInitializedEvent
事件。而Nacos客户端在等这个事件出现才会向服务端注册自己。又因部署在外部Tomcat中就不会初始化内嵌Tomcat,也就没触发这个事件。
所以解决方法就是将Nacos等事件的部分代码调用下,让他们启动注册。
Nacos的自动注册类是 NacosAutoServiceRegistration
,它继承Spring Cloud的AbstractAutoServiceRegistration
,在AbstractAutoServiceRegistration
等的 bind(WebServerInitializedEvent)
方法监听事件,设置端口号并启动注册。这里边 this.port
是从事件中获取的,需要我们自行获取。
设置port的位置可见,是从org.springframework.cloud.client.serviceregistry.Registration
NacosAutoServiceRegistration
, die AbstractAutoServiceRegistration
, AbstractAutoServiceRegistration
und andere bind von Spring Cloud erbt (WebServerInitializedEvent)
-Methode wartet auf Ereignisse, legt die Portnummer fest und startet die Registrierung. Hier wird this.port
von der Veranstaltung abgerufen und muss von uns selbst abgerufen werden.
org.springframework.cloud.client.serviceregistry.Registration
abgerufen . Einfach einstellen. 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); } }
Das obige ist der detaillierte Inhalt vonSo lösen Sie das Problem, wenn SpringBoot auf einem externen Tomcat bereitgestellt wird und nicht beim Nacos-Server registriert werden kann. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!