Tomcat에 배포 시 SpringBoot 프로젝트 War를 Nacos에 등록할 수 없는 문제 해결

문제 설명      

       Tomcat에 배포할 때 Spring Boot 프로젝트를 Nacos에 등록할 수 없는 문제를 해결하는 방법"에서 발생하는 관련 문제를 해결할 수 있기를 바랍니다.

Nacos를 등록 센터로 사용하고 war 패키지 형태로 서버에 배포되는 Spring Boot 프로젝트에서 프로젝트 시작 시 해당 서비스를 Nacos에 등록할 수 없는 것으로 나타났습니다.

분석하다

    소스코드를 보려면 nacos의 등록 클래스에서 찾아야 하는데 검색 결과 nacos 등록 클래스인 NacosAutoServiceRegistration이 Spring Cloud의 AbstractAutoServiceRegistration을 상속하고 Listening 이벤트가 AbstractAutoServiceRegistration에 바인딩되어 빌드된 내용을 수신하는 것으로 확인됩니다. -컨테이너 시동 완료 이벤트에 참여하여 컨테이너 포트를 획득한 후 등록센터에 등록합니다.

@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 자동 설정 포트를 얻을 수 있습니다. 테스트 후 방법이 실현 가능합니다.

코드는 아래와 같이 표시됩니다.

@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 이상 버전을 사용해 보세요.  

Supongo que te gusta

Origin blog.csdn.net/Angel_asp/article/details/132619195
Recomendado
Clasificación