繁体   English   中英

中止Tomcat启动

[英]Abort Tomcat start-up

具体来说,我希望Tomcat在我的Web应用无法初始化(由于配置错误)时中止启动。

  1. 我试图使用Tomcat关闭端口。 当我的Web应用程序启动时,这还没有准备好。

  2. -Dorg.apache.catalina.startup.EXIT_ON_INIT_FAILURE = true,不起作用。 Tomcat启动正常。

  3. 引发未捕获的异常。 我尝试引发异常。 Tomcat仍然可以正确初始化,但是我的Web应用程序处于无法运行的状态。

  4. 使用Tomcat JMX API。 任何一种关闭方法都不会导致Tomcat关闭。

到目前为止,我仅有的其他选择是System.exit(-1) 确实可以,但是我担心对Tomcat这样做会导致问题。

Tomcat旨在针对无法启动的错误编写的应用程序具有弹性。

org.apache.catalina.startup.EXIT_ON_INIT_FAILURE用于在Tomcat的组件之一(例如连接器之一)没有启动(例如,因为端口正在使用)时停止Tomcat。

System.exit()很难看,但是可以正常工作,并且就Tomcat而言是安全的(就此而言,kill -9)。 是应用程序可能不喜欢这种相当残酷的关机方法。

有一种特定于Tomcat的方法可以更干净地执行此操作。 将自定义LifecycleListener添加到服务器组件,并使它响应AFTER_START_EVENT。 让侦听器将容器层次结构从服务器导航到上下文[Server-> Service(s)-> Engine-Host(s)-> Context(s)],并检查每个上下文是否处于STARTED状态。 如果不是,请在服务器上调用stop(),然后调用destroy()。

正如Mark Thomas所提到的,这是侦听器的实现,该实现将中止Tomcat启动。 StrictStateCheckListener是启动后的服务器侦听器。 它检查所有Container的状态,包括引擎,主机和上下文。 如果有任何组件无法启动(状态不同于STARTED ),则服务器启动将中止。

package com.example.lifecycle;

import java.util.logging.*;
import org.apache.catalina.*;

public class StrictStateCheckListener implements LifecycleListener {

  private static final Logger LOGGER = Logger.getLogger(StrictStateCheckListener.class.getName());

  private boolean hasFailures;

  private String containerState;

  @Override
  public void lifecycleEvent(LifecycleEvent event) {
    String type = event.getType();
    Lifecycle lifecycle = event.getLifecycle();

    if (lifecycle instanceof Server && type.equals(Lifecycle.AFTER_START_EVENT)) {
      Server server = (Server) lifecycle;
      hasFailures = false;

      // Check status of each container
      StringBuilder sb = new StringBuilder("Status:").append(System.lineSeparator());
      for (Service service : server.findServices()) {
        checkState(service.getContainer(), sb, "");
      }
      if (LOGGER.isLoggable(Level.INFO)) {
        LOGGER.info(sb.toString());
      }
      if (hasFailures) {
        /*
         * The server will not be stopped by this listener. Indeed,
         * an exception is raised to trigger shutdown hook. See:
         * `org.apache.catalina.startup.Catalina`.
         */
        throw new IllegalStateException(containerState);
      }
    }
  }

  private void checkState(Container container, StringBuilder report, String indent) {
    if (!hasFailures && container.getState() != LifecycleState.STARTED) {
      hasFailures = true;
      containerState = stateOf(container);
    }
    report.append(indent).append(stateOf(container));
    for (Container child : container.findChildren()) {
      checkState(child, report, indent + "  ");
    }
  }

  private String stateOf(Container container) {
    String className = container.getClass().getSimpleName();
    String stateName = container.getStateName();
    return String.format("%s[%s]: %s%n", className, container.getName(), stateName);
  }
}

通过server.xml将此侦听器注册到您的服务器组件:

<Server>
  ...
  <Listener className="com.example.lifecycle.StrictStateCheckListener" />
  ...
</Server>

第一点:您的意思是当您从应用程序中抛出未初始化状态异常时,您正在调用tomcat shutdown.bat文件。您是否尝试过从程序中调用shutdown.bat文件。

我知道这个问题有点老了,但是在这里我要进一步思考,以寻求解决方案。 看来您的要求是在webapp初始化失败时停止tomcat。 这与“中止Tomcat启动”有所不同。 Tomcat本身已经启动,并且将在启动后立即开始部​​署您的Web应用程序。 根据您的要求,我假设您没有任何其他Webapp。 如果是这样,为什么不只使用Spring Boot? Spring Boot提供了一种部署自包含Web应用程序的方法。 在这种情况下,如果初始化失败,则应用程序将无法启动。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM