tomcat 如何优雅关闭?

在Bootstrap类中
public final class Bootstrap {
  public static void main(String[] args) {

    System.setProperty("catalina.base", System.getProperty("user.dir"));
    Connector connector = new HttpConnector();

    Wrapper wrapper1 = new StandardWrapper();//表示一个servlet容器
    wrapper1.setName("Primitive");
    wrapper1.setServletClass("PrimitiveServlet");
    Wrapper wrapper2 = new StandardWrapper();
    wrapper2.setName("Modern");
    wrapper2.setServletClass("ModernServlet");

    Context context = new StandardContext();
    // StandardContext's start method adds a default mapper
    context.setPath("/app1");
    context.setDocBase("app1");

    context.addChild(wrapper1);
    context.addChild(wrapper2);

    LifecycleListener listener = new SimpleContextConfig();
    ((Lifecycle) context).addLifecycleListener(listener);

    Host host = new StandardHost();
    host.addChild(context);
    host.setName("localhost");
    host.setAppBase("webapps");

    Loader loader = new WebappLoader();
    context.setLoader(loader);
    // context.addServletMapping(pattern, name);
    context.addServletMapping("/Primitive", "Primitive");
    context.addServletMapping("/Modern", "Modern");

    Engine engine = new StandardEngine();
    engine.addChild(host);
    engine.setDefaultHost("localhost");

    Service service = new StandardService();
    service.setName("Stand-alone Service");

    Server server = new StandardServer();
    server.addService(service);

    service.addConnector(connector);
    //StandardService class's setContainer will call all its connector's setContainer method
    service.setContainer(engine);

    // Start the new server
    if (server instanceof Lifecycle) {
      try {
        //最终调用services[i].initialize(); 该方法用于初始化添加到其中的所有连接器.
        //那么连接器要初始化什么东西呢?-->打开socket开始监听
        server.initialize();


        //该方法最后会启动container,connectors。利用for启动多个。
        //那么启动什么东西呢?-->每一个组件启动都会发送相关事件,
        ((Lifecycle) server).start();
        server.await();//等待关闭命令--这里关闭
        // the program waits until the await method returns,
        // i.e. until a shutdown command is received.
      }
      catch (LifecycleException e) {
        e.printStackTrace(System.out);
      }
    }

    //这里开始关闭啦 !
    if (server instanceof Lifecycle) {
      try {
        ((Lifecycle) server).stop();
      }
      catch (LifecycleException e) {
        e.printStackTrace(System.out);
      }
    }
  }
}

看看StandardServer#await()方法


public void await() {

    // Set up a server socket to wait on
    ServerSocket serverSocket = null;
    try {
        serverSocket = new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));
    } catch (IOException e) {
        System.err.println("StandardServer.await: create[" + port + "]: " + e);
        e.printStackTrace();
        System.exit(1);
    }

    // Loop waiting for a connection and a valid command
    while (true) {

        // Wait for the next connection
        Socket socket = null;
        InputStream stream = null;
        try {
            socket = serverSocket.accept();
            socket.setSoTimeout(10 * 1000);  // Ten seconds
            stream = socket.getInputStream();
        } catch (AccessControlException ace) {
            System.err.println("StandardServer.accept security exception: " + ace.getMessage());
            continue;
        } catch (IOException e) {
            System.err.println("StandardServer.await: accept: " + e);
            e.printStackTrace();
            System.exit(1);
        }

        // Read a set of characters from the socket
        StringBuffer command = new StringBuffer();
        int expected = 1024; // Cut off to avoid DoS attack
        while (expected < shutdown.length()) {
            if (random == null)
                random = new Random(System.currentTimeMillis());
            expected += (random.nextInt() % 1024);
        }
        while (expected > 0) {
            int ch = -1;
            try {
                ch = stream.read();
            } catch (IOException e) {
                System.err.println("StandardServer.await: read: " + e);
                e.printStackTrace();
                ch = -1;
            }
            if (ch < 32)  // Control character or EOF terminates loop
                break;
            command.append((char) ch);
            expected--;
        }

        // Close the socket now that we are done with it
        try {
            socket.close();
        } catch (IOException e) {
            ;
        }

        // Match against our command string
        boolean match = command.toString().equals(shutdown);
        if (match) {
            break;
        } else
            System.err.println("StandardServer.await: Invalid command '" +
                               command.toString() + "' received");

    }

    // Close the server socket and return
    try {
        serverSocket.close();
    } catch (IOException e) {
        ;
    }

}










先调用StandardServer的stop()方法 关闭与它关联的组件

StandardServer
public void stop() throws LifecycleException {

    // Validate and update our current component state
    if (!started)
        throw new LifecycleException(sm.getString("standardServer.stop.notStarted"));

    // Notify our interested LifecycleListeners
    lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);

    lifecycle.fireLifecycleEvent(STOP_EVENT, null);
    started = false;

    // Stop our defined Services
    for (int i = 0; i < services.length; i++) {
        if (services[i] instanceof Lifecycle)
            ((Lifecycle) services[i]).stop();//关闭所有service,即调用StandardService的stop()
    }

    // Notify our interested LifecycleListeners
    lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);

}


复制代码

StandardService
public void stop() throws LifecycleException {

    // Validate and update our current component state
    if (!started) {
        throw new LifecycleException
            (sm.getString("standardService.stop.notStarted"));
    }

    // Notify our interested LifecycleListeners
    lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);

    lifecycle.fireLifecycleEvent(STOP_EVENT, null);

    System.out.println
        (sm.getString("standardService.stop.name", this.name));
    started = false;

    // Stop our defined Connectors first
    synchronized (connectors) {
        for (int i = 0; i < connectors.length; i++) {
            if (connectors[i] instanceof Lifecycle)
                ((Lifecycle) connectors[i]).stop();//1关闭连接器
        }
    }

    // Stop our defined Container second
    if (container != null) {
        synchronized (container) {
            if (container instanceof Lifecycle) {
                ((Lifecycle) container).stop();//2关闭容器
            }
        }
    }

    // Notify our interested LifecycleListeners
    lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);

}复制代码

#1:for循环关闭所有连接器。(即调用connector的stop方法)如下

HttpConnector
public void stop() throws LifecycleException {

    // Validate and update our current state
    if (!started)
        throw new LifecycleException(sm.getString("httpConnector.notStarted"));
    lifecycle.fireLifecycleEvent(STOP_EVENT, null);
    started = false;

    // Gracefully shut down all processors we have created
    for (int i = created.size() - 1; i >= 0; i--) {
        HttpProcessor processor = (HttpProcessor) created.elementAt(i);
        if (processor instanceof Lifecycle) {
            try {
                ((Lifecycle) processor).stop();//1)
            } catch (LifecycleException e) {
                log("HttpConnector.stop", e);
            }
        }
    }

    synchronized (threadSync) {
        // Close the server socket we were using
        if (serverSocket != null) {
            try {
                serverSocket.close();
            } catch (IOException e) {

            }
        }
        // Stop our background thread
        threadStop();
    }
    serverSocket = null;

}

1)关闭所有processor。代码如下
public void stop() throws LifecycleException {

    if (!started)
        throw new LifecycleException(sm.getString("httpProcessor.notStarted"));
    lifecycle.fireLifecycleEvent(STOP_EVENT, null);
    started = false;

    threadStop();

}
private void threadStop() {

    log(sm.getString("httpProcessor.stopping"));

    stopped = true;
    assign(null);

    if (status != Constants.PROCESSOR_IDLE) {
        // Only wait if the processor is actually processing a command
        synchronized (threadSync) {
            try {
                threadSync.wait(5000);
            } catch (InterruptedException e) {
                ;
            }
        }
    }
    thread = null;

}

复制代码


#2:关闭container组件。调用其stop方法。

StandardContext复制代码

public synchronized void stop() throws LifecycleException {

    // Validate and update our current component state
    if (!started)
        throw new LifecycleException(sm.getString("containerBase.notStarted", logName()));
    if (debug >= 1)
        log("Stopping");
    // Notify our interested LifecycleListeners
    lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);
    // Mark this application as unavailable while we shut down
    setAvailable(false);//服务设为不可用
    // Binding thread
    ClassLoader oldCCL = bindThread();
    // Stop our filters
    filterStop();//关闭过滤器

    // Finalize our character set mapper
    setCharsetMapper(null);

    if ((manager != null) && (manager instanceof Lifecycle)) {
        ((Lifecycle) manager).stop();//关闭管理器
    }

    // Normal container shutdown processing
    if (debug >= 1)
        log("Processing standard container shutdown");
    // Notify our interested LifecycleListeners
    lifecycle.fireLifecycleEvent(STOP_EVENT, null);
    started = false;

    try {
        // Stop the Valves in our pipeline (including the basic), if any
        if (pipeline instanceof Lifecycle) {
            ((Lifecycle) pipeline).stop();//关闭管道
        }
        // Stop our child containers, if any
        Container children[] = findChildren();
        for (int i = 0; i < children.length; i++) {
            if (children[i] instanceof Lifecycle)
                ((Lifecycle) children[i]).stop();//关闭所有子容器
        }
        // Stop our Mappers, if any
        Mapper mappers[] = findMappers();
        for (int i = 0; i < mappers.length; i++) {
            if (mappers[(mappers.length-1)-i] instanceof Lifecycle)
                ((Lifecycle) mappers[(mappers.length-1)-i]).stop();//关闭映射器
        }
        // Stop our application listeners
        listenerStop();//关闭监听器
        // Stop our subordinate components, if any
        if (resources != null) {
            if (resources instanceof Lifecycle) {
                ((Lifecycle) resources).stop();
            } else if (resources instanceof ProxyDirContext) {
                DirContext dirContext =
                    ((ProxyDirContext) resources).getDirContext();
                if (dirContext != null) {
                    if (debug >= 1) {
                        log("Releasing document base " + docBase);
                    }
                    if (dirContext instanceof BaseDirContext) {
                        ((BaseDirContext) dirContext).release();
                        if ((dirContext instanceof WARDirContext)
                            || (dirContext instanceof FileDirContext)) {
                            resources = null;
                        }
                    } else {
                        log("Cannot release " + resources);
                    }
                }
            }
        }
        if ((realm != null) && (realm instanceof Lifecycle)) {
            ((Lifecycle) realm).stop();
        }
        if ((cluster != null) && (cluster instanceof Lifecycle)) {
            ((Lifecycle) cluster).stop();
        }
        if ((logger != null) && (logger instanceof Lifecycle)) {
            ((Lifecycle) logger).stop();
        }
        if ((loader != null) && (loader instanceof Lifecycle)) {
            ((Lifecycle) loader).stop();
        }

    } finally {

        // Unbinding thread
        unbindThread(oldCCL);

    }

    // Reset application context
    context = null;

    // Notify our interested LifecycleListeners
    lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);

    if (debug >= 1)
        log("Stopping complete");

}复制代码



转载于:https://juejin.im/post/5b1602846fb9a01e345b966f

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要关闭Tomcat服务器,可以按照以下步骤: 1. 在Eclipse,选择“Servers”视图,找到正在运行的Tomcat服务器。 2. 右键单击服务器,选择“Stop”或“Stop Server”选项。 3. 等待一段时间,直到服务器完全停止。 4. 如果需要,可以在“Servers”视图删除服务器。 注意:在关闭Tomcat服务器之前,应该确保所有正在运行的应用程序都已经停止。否则,可能会出现数据丢失或其他问题。 ### 回答2: Eclipse是一款常用的集成开发环境(IDE),用于开发Java应用程序。在使用Eclipse进行Java开发过程,我们通常需要使用Tomcat作为Web服务器来运行Java Web应用程序。但是,有时候我们需要关闭Tomcat服务器,本文将介绍如何在Eclipse关闭Tomcat服务器。 关闭Tomcat服务器的步骤如下: 1. 在Eclipse的“Servers”视图,选择要关闭Tomcat服务器,右键单击服务器,选择“Stop”或“Stop Server”菜单项。 2. 点击“OK”按钮以确认关闭服务器。 3. 当服务器停止后,将显示“Server Stopped”消息提示。 4. 如果您不再需要该服务器,请右键单击它并选择“Delete”菜单项以删除服务器。 5. 如果您只是希望暂时停用服务器而不是删除它,请右键单击服务器并选择“Remove from View”菜单项,在“Servers”视图隐藏服务器。 总结一下,关闭Tomcat服务器在Eclipse非常简单。只需右键单击服务器并从选项选择“停止”或“删除”即可。这将确保服务器在后台不再运行,节省计算机资源并帮助延长计算机的使用寿命。 ### 回答3: 在使用Eclipse进行Web开发时,我们经常需要启动和关闭Tomcat服务器。下面是在Eclipse关闭Tomcat服务器的简单步骤。 1. 打开Eclipse,并切换到Servers视图。在这个视图,你可以看到Tomcat服务器的状态。 2. 选需要关闭Tomcat服务器,右键单击,并选择“Stop”选项。 3. 稍等片刻,直到服务器完全停止运行。在这个过程,Eclipse会向服务器发出停止服务请求,服务器将依次关闭所有正在运行的应用程序。 4. 一旦服务器完全停止,你会在Servers视图看到服务器已经被标记为“Stopped”。 请注意,有时候关闭服务器可能需要一些时间,特别是在服务器正在处理繁重的工作负载时。在这种情况下,请耐心等待服务器完全停止,以确保您的数据安全。同时,你可以通过查看服务器日志来获取有关服务器运行情况的详细信息,以便更好地了解服务器的运行状况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值