解决SpringBoot项目war部署到tomcat下无法Nacos中注册服务问题

问题说明

怎么解决Spring Boot项目部署到tomcat下无法Nacos中注册服务问题",希望能够解决您遇到有关问题。

在使用Nacos作为注册中心的Spring Boot项目,以war包形式部署到服务器上,启动项目发现该服务无法在Nacos中注册。

分析

查看源码,需从nacos的注册类找起,查找后发现,nacos注册类NacosAutoServiceRegistration继承了Spring Cloud中AbstractAutoServiceRegistration, 而在AbstractAutoServiceRegistration中绑定了一个监听事件,监听内置容器启动完成事件,监听到获取容器端口后向注册中心注册。

java 复制代码
@EventListener({WebServerInitializedEvent.class})
    public void bind(WebServerInitializedEvent event) {
        ApplicationContext context = event.getApplicationContext();
        if (!(context instanceof ConfigurableWebServerApplicationContext) || !"management".equals(((ConfigurableWebServerApplicationContext)context).getServerNamespace())) {
            this.port.compareAndSet(0, event.getWebServer().getPort());
            this.start();
        }

}

而使用外部容器时,不能监听到事件,所以自动注册失败。

解决方案

Spring Boot提供了PostConstruct注解属性和ApplicationRunner接口并实现run方法即可前者比较简单,是在应用起好之后执行一些初始化动作。通过这个接口我们可以实现启动项目后注册服务。使用这种方法,需要在配置文件中配置端口号,如果一个应用部署很多端口,每个应用都要配置,很不方便。故可获取外部tomcat自动设置端口。经测试,方法可行。

代码如下:

java 复制代码
@Component
@Slf4j
public class NacosRegister {

    @Autowired
    private NacosRegistration registration;

    @Autowired
    private NacosAutoServiceRegistration nacosAutoServiceRegistration;

    @Value("${server.port}")
    String serverPort;

    @PostConstruct
    public void registerInstance() throws Exception {
        if (registration != null && serverPort != null) {
            String tomcatPort = serverPort;
            try {
                tomcatPort = getPort();
            } catch (Exception e) {
                log.warn("获取外部Tomcat端口异常:", e);
            }
            registration.setPort(Integer.parseInt(tomcatPort));
            nacosAutoServiceRegistration.start();
        }
    }

    /**
     * 获取外部tomcat端口
     */
    public String getPort() {
        try {
            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 port;
        } catch (Exception ex) {
            log.error("NacosRegister.getPort()动态获取端口异常:", ex.toString());
            return serverPort;
        }
    }

提示

部署项目要注意版本问题,如Spring Boot 2.0.6应该部署在tomcat8以上版本,tomcat8以下版本可能有些变化,导致项目启动报错。所以大家尽量使用tomcat8以上版本吧

相关推荐
树℡独5 小时前
ns-3仿真之应用层(五)
服务器·网络·tcp/ip·ns3
a41324476 小时前
ubuntu 25 安装vllm
linux·服务器·ubuntu·vllm
Configure-Handler6 小时前
buildroot System configuration
java·服务器·数据库
津津有味道6 小时前
易语言TCP服务端接收刷卡数据并向客户端读卡器发送指令
服务器·网络协议·tcp·易语言
Fᴏʀ ʏ꯭ᴏ꯭ᴜ꯭.7 小时前
Keepalived VIP迁移邮件告警配置指南
运维·服务器·笔记
Genie cloud7 小时前
1Panel SSL证书申请完整教程
服务器·网络协议·云计算·ssl
一点程序7 小时前
基于SpringBoot的选课调查系统
java·spring boot·后端·选课调查系统
!chen8 小时前
linux服务器静默安装Oracle26ai
linux·运维·服务器
莫大3308 小时前
2核2G云服务器PHP8.5+MySQL9.0+Nginx(LNMP)安装WordPress网站详细教程
运维·服务器·nginx
2501_927773078 小时前
imx6驱动
linux·运维·服务器