SpringBoot部署到外部Tomcat无法注册到Nacos服务端
事情经过
近期做一个项目投标演示(POC)环境支持,需要集成Nacos服务端。考虑到现有项目中已经有了Nacos相关依赖,那还不简单?新建个服务端,配置几下重启不就搞定了吗?然而事情远没有想得这么简单。同样的代码在我本地IDE里运行就能注册成功,在演示环境 Tomcat+War 部署就不行了。
经过远程Debug代码,发现Nacos客户端的线程都有启动,却没有注册成功。
思路
想到可能与Tomcat部署模式有关系,就去查了官方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
大致是说只有当 Spring Boot 启动内嵌 Tomcat 成功后,才会发布 WebServerInitializedEvent 事件。而Nacos客户端在等这个事件出现才会向服务端注册自己。又因部署在外部Tomcat中就不会初始化内嵌Tomcat,也就没触发这个事件。
所以解决方法就是将Nacos等事件的部分代码调用下,让他们启动注册。
Nacos的自动注册类是 NacosAutoServiceRegistration,它继承Spring Cloud的AbstractAutoServiceRegistration,在AbstractAutoServiceRegistration等的 bind(WebServerInitializedEvent)方法监听事件,设置端口号并启动注册。这里边 this.port 是从事件中获取的,需要我们自行获取。

设置port的位置可见,是从org.springframework.cloud.client.serviceregistry.Registration中取到的,给它设置一下就可以了。

解决办法
我写了一个完整的配置类放到了该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);
}
}
经过我这一波操作问题终于解决了。我是Hellxz,不在进坑就在爬坑的路上。
SpringBoot部署到外部Tomcat无法注册到Nacos服务端的更多相关文章
- 将SpringBoot部署在外部tomcat中
一,前言 在文章SpringBoot之简单入门中提到了,SpringBoot是内置一个tomcat容器的,但是如果要将SpringBoot部署在一个外部的tomcat,要怎么办呢?这就是本篇文章的目的 ...
- SpringBoot应用War包形式部署到外部Tomcat
这一篇文章介绍SpringBoot应用修改默认打jar形式部署为打war包形式,部署到外部Tomcat. SpringBoot应用默认打包成为可执行jar模式让我们感觉到部署的便捷,接下来给大家介绍一 ...
- SpringBoot_11_将springboot项目部署到外部tomcat上
一.前言 二. 三.参考资料 如何将Spring Boot项目打包部署到外部Tomcat 2.SpringBoot 项目如何在tomcat容器中运行
- SpringBoot以war包形式部署到外部Tomcat
SpringBoot 项目打包时能打成 .jar 与 .war包文件,.jar使用 java -jar xx.jar 就可以启动,而 .war 可以部署到tomcat的 webapps 中,随tomc ...
- spring boot 打包war后 部署到外部 tomcat 的具体正确操作【包括修改端口 与 去除请求路径的工程名】
1.前言 工程做好了,总不能放在idea运行吧?不然怎么把项目放到云服务器呢?[这一篇随笔不讲解发布的云服务器的操作,在其他随笔有详细记载.] 解决的方案是把springboot 工程 打包成war文 ...
- Maven入门示例(3):自动部署至外部Tomcat
Maven入门示例(3):自动部署至外部Tomcat 博客分类: maven 2012原创 Maven入门示例(3):自动部署至外部Tomcat 上一篇,介绍了如何创建Maven项目以及如何在内 ...
- springboot项目怎么部署到外部tomcat
spring-boot项目中,默认提供内嵌的tomcat,所以打包直接生成jar包,用Java -jar命令就可以启动. 但是也有一定的需求,会使用外部tomcat来部署项目.下面来看: 1.新建项目 ...
- SpringBoot打war包并部署到外部tomcat运行(jar工程改造为正war工程)
如果你的SpringBoot工程是一个jar工程,而想把它改造成war工程,并打成war包放到外部的tomcat下运行,该怎么修改配置呢?这里以Maven工程为例进行介绍. (1)将pom.xml中的 ...
- 如何将Spring Boot项目打包部署到外部Tomcat
1.项目打包 项目开发结束后,需要打包部署到外部服务器的Tomcat上,主要有几种方式. (1)生成jar包 cd 项目跟目录(和pom.xml同级)mvn clean package## 或 ...
- Spring Boot项目部署到外部Tomcat服务器
2017年04月27日 23:33:52 阅读数:7542 前言 Spring Boot项目一般都是内嵌tomcat或者jetty服务器运行,很少用war包部署到外部的服务容器,即使放到linux中, ...
随机推荐
- stopping hbasecat:/tmp/hbase-root-master.pid:No such file or directory
今天在新电脑上安装虚拟机的时候,尝试打开hadoop和hbase,hadoop打开没有问题,就是hbase关闭的时候报了stopping hbasecat:/tmp/hbase-root-master ...
- MFC中利用CFileDialog选择文件并读取文件所遇到的问题和解决方法
在用MFC编写一个上位机时,需要实现选择和读取一个二进制文件,本来以为很简单的但是在实现过程中遇到很多问题,所幸都一一解决,这里做一下记录. 首先在实现文件选择,在界面上设置一个按钮,并在点击事件函数 ...
- calibredrv命令
flattencell: set L1 [layout create *.gds -dt_expand] $L1 flatten cell TOP_CELL_NAME $L1 gdsout ./*_f ...
- 【BOOK】Ajax数据爬取
Requests获取原始HTML文档,Ajax加载和JavaScript处理的数据无法获得 一.Ajax Ajax-异步的JavaScript和XML Ajax请求页面更新: 1. 发送请求 2. 解 ...
- 20202411 2020-2021-2 《Python程序设计》实验三报告
20202411 2020-2021-2 <Python程序设计>实验三报告 课程:<Python程序设计> 班级: 2024 姓名: 陈书桓 学号:20202411 实验教师 ...
- 【APT】响尾蛇(SideWinder)Hta文件自动解密C2
前言 一个用于从SideWinder APT组织常用的hat文件中解密C2链接地址的Python脚本,示例代码对一些老的hat文件效果比较好,新的样本可能需要根据实际情况修改下,最初是用于对VT上命中 ...
- vue组件 子组件没有事件怎么 向父组件传递数据
通过ref去接收值!!! 需求图片 代码实现 //----------父组件 <div class="fingerprint-bottom"> <el-tabs ...
- python之变量
什么是变量? 用来记录事务的变化状态,计算机模拟人,就需要具备人类某一个功能.你通过记录我的名字年龄等一系列的身份信息,以此和我进行匹配,确定我就是phoebe这个人. 为什么有变量? 游戏里的英雄角 ...
- Navicat Premium 12 安装破解过程 (经过测试)
@ 目录 下载安装 下载 解压文件目录 安装使用步骤截图 1. 安装navicat120_premium_cs_x64.exe 软件 2. 解压Navicat.Premium 破解补丁.rar 3. ...
- 二,使用axios
1,下载https://unpkg.com/axios@1.3.2/dist/axios.min.js保存在js目录下,命名为axios.js 2,http.js let baseUrl = &quo ...