最近把一个 SpringBoot 项目接入了微服务,使用 SpringBoot 2.1.9.RELASE 和 SpringCloud Greewich.SR3 。本地测试都正常,但是上线后,出现了一个这样一个情况:

日志未出现 Nacos Registery 类似的语句,也没有任何异常信息,就像是压根就没有配置微服务一样。

检查了配置文件,正常

本地测试,正常注册

后来找组长帮忙看了一下,发现是 war 包部署的问题:

SpringCloud 项目打 war 包部署时,也就是使用外部 Tomcat 部署,其启动命令、端口等是由外部容器 Tomcat 配置的,而 Nacos 或者其他服务注册方式需要当前项目的端口号用于注册微服务。

以 Nacos 为例,其自动注册微服务的类是 NacosAutoServiceRegistration,我们看一下它的源码:

public class NacosAutoServiceRegistration extends AbstractAutoServiceRegistration {

private NacosRegistration registration;

@Deprecated

public void setPort(int port) {

this.getPort().set(port);

}

protected NacosRegistration getRegistration() {

if (this.registration.getPort() < 0 && this.getPort().get() > 0) {

this.registration.setPort(this.getPort().get());

}

Assert.isTrue(this.registration.getPort() > 0, "service.port has not been set");

return this.registration;

}

我们看到 NacosAutoServiceRegistration 使用了 this.registration.setPort(this.getPort().get()); 来设置端口号。

而端口号是从其父类 AbstractAutoServiceRegistration 中的方法获取的:

public abstract class AbstractAutoServiceRegistration

implements AutoServiceRegistration, ApplicationContextAware,

ApplicationListener {

private AtomicInteger port = new AtomicInteger(0);

@Deprecated

public void bind(WebServerInitializedEvent event) {

ApplicationContext context = event.getApplicationContext();

if (context instanceof ConfigurableWebServerApplicationContext) {

if ("management".equals(((ConfigurableWebServerApplicationContext) context)

.getServerNamespace())) {

return;

}

}

this.port.compareAndSet(0, event.getWebServer().getPort());

this.start();

}

这段代码监听了内置容器启动完成事件,监听获取到容器端口后,向注册中心注册服务。

因此,当使用外部容器时,如此处的 Tomcat 来部署项目,AbstractAutoServiceRegistration 就不能监听到容器启动事件了,也就不会尝试向服务注册中心注册当前这个微服务,那么注册就失败了,并且也就没有异常信息了。

解决办法是自定义获取获取外部容器端口的方法, 然后监听应用启动事件,当应用被启动时,获取外部容器启动的端口号,然后将这个 port 设置到 NacosAutoServiceReigistration 中。

下面是完整的解决方法:

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.boot.ApplicationArguments;

import org.springframework.boot.ApplicationRunner;

import org.springframework.cloud.alibaba.nacos.registry.NacosAutoServiceRegistration;

import org.springframework.stereotype.Component;

import javax.management.MBeanServer;

import javax.management.ObjectName;

import javax.management.Query;

import java.lang.management.ManagementFactory;

import java.util.Set;

@Component

public class NacosConfig implements ApplicationRunner {

@Autowired(required = false)

private NacosAutoServiceRegistration registration;

@Value("${server.port}")

Integer port;

@Override

public void run(ApplicationArguments args) {

if (registration != null && port != null) {

Integer tomcatPort = port;

try {

tomcatPort = new Integer(getTomcatPort());

} catch (Exception e) {

e.printStackTrace();

}

registration.setPort(tomcatPort);

registration.start();

}

}

/**

* 获取外部tomcat端口

*/

public String getTomcatPort() throws Exception {

MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();

Set 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 port;

}

}

交流学习

个人微信:guanlanju6688

公众号:猿生物语,"分享技术,也感悟人生",欢迎关注!

本地服务注册不上nacos_SpringCloud War 包部署导致服务未正常注册到 Nacos 问题相关推荐

  1. SpringBoot微服务项目构建war包 部署排除指定jar

    文章目录 一.构建war包部署SpringBoot项目 二.构建war包 2.1. 适用范围 2.2. 构建war包 三.部署排除指定jar 3.1. 下载排除插件 3.2. 搜索部署排除指定jar ...

  2. mvn打包并部署本地tomcat_Maven项目打包成war包部署到Tomcat的方法

    Maven项目打包成war包部署到Tomcat的方法 有关于 Maven 项目的打包部署,我这里用的是 Eclipse 编辑器,以此来做个简单的记录. 实践环境 操作系统: Windows IDE: ...

  3. Linux中把文件夹打成war包,SpringBoot中maven项目打成war包部署在liunx服务器上的方法...

    说明:Spring Boot由于内嵌了如Tomcat,Jetty和Undertow这样的容器,也就是说可以直接跑起来,用不着再像Spring项目还需要外置的Tomcat等容器来进行部署工作了,通过启动 ...

  4. Linux上更新war包

    为了防止自己忘记,把在公司学习的更新war包的过程记录一下. 1.先介绍一下连接xshell和xftp的方式 (1)xshell是为了连接到Linux服务器,打开xshell,新建连接,输入连接名和I ...

  5. 记录这两年的学习以及简述这次基于springboot框架的课程设计和打war包部署的坑

    一.前言 一想都是满满的经历呀.如果不想看我废话,可以直接跳到后面. 1 关于编程 1.1 C.C++ 作为一名软件工程生,编程是我以后自力更生的必备技能.奈何大一的我不懂得轻重,基本没有把精力放在编 ...

  6. SpringBoot项目打成war包部署到外部Tomact运行

    需求:使用SpringBoot自带的Tomact在线上环境部署特别不方便,尤其是只更改几个文件就得全部打包部署,所以需要把SpringBoot打成war包部署到Tomact 1.在pom.xml中 由 ...

  7. SpringBoot之打包成war包部署到tomcat

    SpringBoot打包成war包部署到tomcat 小编花费了九牛二虎之力,总算把SpringBoot项目成功打包成war包,其中不免遇到了一些小状况,特写此文,以便其他小伙伴们不要走我的老路,避免 ...

  8. 将JavaWeb项目war包部署到阿里云服务器

    文章目录 JavaWeb项目部署到阿里云服务器 1. 把项目打包成war包 1.1 方法一 1.2 方法二 2. 配置服务器的jdk和tomcat环境 3. JavaWeb项目部署 JavaWeb项目 ...

  9. RedHat搭建Web运用之War包部署和脚本更新(四)

    开心一笑 [教室里小兰问小毅说:师哥到底是师还是哥啊? 小毅说:当然是哥啊! 小兰问:为什么呢? 小毅说:那你说汽车到底是汽还是车啊!] 视频教程 大家好,我录制的视频<Java之优雅编程之道& ...

最新文章

  1. MySQL数据库导入或者同步大量数据时数据丢失解决方案
  2. 【laravel5.4 + TP5.0】hasOne和belongsTo的区别
  3. 【BIM入门实战】Revit 2018模型设计阶段重点及注意事项总结
  4. tkinter 菜单添加事件_Tasker的最新测试劫持了Android 11的电源菜单
  5. Elasticsearch基本操作 1:ES 基本操作、批处理
  6. excel2003和excel2007文件的创建和读取
  7. mysql8.0.15源码linux_源码安装mysql8.0.20
  8. 揭示Win32 API拦截细节/API hooking revealed (2)
  9. python进阶12 Redis
  10. Tomcat下载及安装(Windows)
  11. 真香警告!java时间格式转换工具
  12. 小米安装linux驱动怎么安装教程,小米手机驱动程序怎么安装教程【图文版】
  13. 张家口地区某一级公路设计--河北建筑工程学院
  14. 数据库SQL语句练习一
  15. kityminder-editor 百度脑图与my-mind 使用体验
  16. Airbnb产品运营分析报告
  17. 基于JavaEE的开放平台出租车系统_JSP网站设计_MySQL数据库设计
  18. jquery--拖拽效果
  19. 基于JSP的宠物狗交易网站
  20. IDM移动端功能升级说明

热门文章

  1. 项目经理对项目各阶段需求的把控力度
  2. 微信小程序canvas实现简易手写签名版(uni-app)
  3. 棉花糖无线点单服务器授权文件,南昌免费无线点菜系统_南昌棉花糖免费餐饮管理系统软件...
  4. 问题 J: 精挑细选
  5. 蓝湖、Cutterman使用方法
  6. 【Web安全】几款web安全查杀工具
  7. areas表-省市区
  8. AcWing 257. 关押罪犯
  9. shopify api php 开发,Shopify 脚本 API 参考
  10. 这可能是用 Markdown 写微信公众号的终极解决方案