java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Spring Boot打WAR包无法注册到Nacos

Spring Boot应用打WAR包后无法注册到Nacos的问题及解决方法

作者:柳岸花开

当我们将 Spring Boot 应用打包成 WAR 并部署到外部 Tomcat 服务器时,可能会遇到服务无法注册到 Nacos 的情况,其原因主要是应用获取不到正确的服务器端口,下面给大家介绍Spring Boot 应用打 WAR 包后无法注册到 Nacos的问题及解决方法,感兴趣的朋友跟随小编一起看看吧

在微服务架构中,服务注册与发现是至关重要的一环。Nacos 作为阿里巴巴开源的注册中心,能够很好地满足这一需求。然而,在将 Spring Boot 应用打包成 WAR 部署到外部服务器时,可能会遇到服务无法注册到 Nacos 的问题。本文将详细讲解这一问题的解决方案。

问题描述

在开发过程中,通常使用 JAR 包运行 Spring Boot 应用,这种方式下,服务注册到 Nacos 通常没有问题。然而,当我们将 Spring Boot 应用打包成 WAR 并部署到外部 Tomcat 服务器时,可能会遇到服务无法注册到 Nacos 的情况。其原因主要是应用获取不到正确的服务器端口。

解决方案

为了在 WAR 包部署时正确地注册服务到 Nacos,我们需要动态地获取实际使用的服务器端口,并将其设置到 Nacos 的服务注册中。以下是一个具体的实现代码:

import com.alibaba.cloud.nacos.registry.NacosAutoServiceRegistration;
import lombok.extern.slf4j.Slf4j;
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.boot.autoconfigure.condition.ConditionalOnProperty;
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;
/**
 * 解决 Spring Boot 应用打 WAR 包后无法注册到 Nacos 的问题
 * 通过动态获取服务器端口并注册到 Nacos
 */
@Slf4j
@ConditionalOnProperty(prefix = "project.deploy", name = "mode", havingValue = "war")
@Component
public class NacosConfig implements ApplicationRunner {
    @Autowired
    private NacosAutoServiceRegistration registration;
    @Value("${server.port:8080}")
    Integer port;
    @Override
    public void run(ApplicationArguments args) {
        if (registration != null && port != null) {
            Integer serverPort = port;
            try {
                serverPort = new Integer(getServerPort());
            } catch (Exception e) {
                log.warn("getServerPort warn", e);
                log.info("getServerPort fail, use the config-file's port {}", port);
            }
            registration.setPort(serverPort);
            registration.start();
        }
    }
    /**
     * 获取实际使用的服务器端口
     */
    public String getServerPort() throws Exception {
        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");
        log.debug("getServerPort {}", port);
        return port;
    }
}

代码解析

1. 类与注解

@Slf4j
@ConditionalOnProperty(prefix = "project.deploy", name = "mode", havingValue = "war")
@Component
public class NacosConfig implements ApplicationRunner {

2. 自动注入与配置

@Autowired
private NacosAutoServiceRegistration registration;
@Value("${server.port:8080}")
Integer port;

3. 启动时设置端口

@Override
public void run(ApplicationArguments args) {
    if (registration != null && port != null) {
        Integer serverPort = port;
        try {
            serverPort = new Integer(getServerPort());
        } catch (Exception e) {
            log.warn("getServerPort warn", e);
            log.info("getServerPort fail, use the config-file's port {}", port);
        }
        registration.setPort(serverPort);
        registration.start();
    }
}

4. 获取实际端口

public String getServerPort() throws Exception {
    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");
    log.debug("getServerPort {}", port);
    return port;
}

通过 JMX 管理接口获取实际使用的 HTTP 端口。

总结

通过上述代码,我们可以实现在 Spring Boot 应用启动时,动态获取并设置 Nacos 注册的端口号。这对于在不同环境中部署应用非常有用,可以避免硬编码端口号带来的问题。同时,结合 Nacos 的服务注册与发现功能,可以更加灵活地管理微服务架构中的各个服务。

到此这篇关于Spring Boot 应用打 WAR 包后无法注册到 Nacos怎么办的文章就介绍到这了,更多相关Spring Boot打 WAR 包无法注册到 Nacos内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文