【问题标题】:shutdown / undeploy tomcat from Servlet从 Servlet 关闭 / 取消部署 tomcat
【发布时间】:2009-10-08 12:41:26
【问题描述】:

我在 Tomcat 中有一个加载关键数据的初始化 servlet。有时需要中止某些错误的启动。

如何在不调用System.exit(1) 的情况下优雅地关闭已部署的应用程序/整个应用程序服务器

我想避免通过端口调用关闭 servlet,因为这在我的安装中没有配置。

可能有一些任务需要在 web.xml 中定义的关闭时从侦听器运行

【问题讨论】:

    标签: java tomcat shutdown


    【解决方案1】:

    首先,您永远不应该从 servlet 容器中调用 System.exit(),因为可能有其他应用程序在与您的进程相同的进程中运行,并且强行终止整个进程是非常不正确的。

    假设您的“init servlet”实现了ServletContextListener,API/接口中没有定义正式的方式来向 servlet 容器发出信号“请巧妙地关闭应用程序”。但是,您可以从contextInitialized() 方法中抛出某种RuntimeException,这在大多数容器(至少是Tomcat)中会停止您的webapp 的启动并使其处于“停止”状态。但是我怀疑 Tomcat 是否会继续调用您的关闭侦听器。

    您可能需要重新考虑您的设计,以便您的关键数据/关闭逻辑不会与 servlet 容器的生命周期紧密相关。

    【讨论】:

    • 更多关于关闭实用程序线程和正确写入日志
    • 我曾经与一个坏的应用程序共享一个 Tomcat,该应用程序一直耗尽内存。当我检测到这一点时,我调用 System.exit(0)。关闭与 Tomcat 中的其他方法一样优雅。
    • 好吧,如果你得到了 OOM,那么此时除了关闭 JVM 之外别无他法。
    • 如果您遇到内存不足的错误,您应该修复错误的 servlet,而不是养成使用System.exit 使服务器崩溃的习惯。
    • 一个澄清:ServletContextListener 的实现不必是 Servlet,它可以是实现两个方法的接口的 POJO 类。顺便说一句,现在让 Servlet 容器识别、加载和执行侦听器的最简单方法是简单地使用 @WebListener 进行注释。这样的侦听器是您执行 Web 应用程序设置和拆卸的预期挂钩,保证在第一次/最后一次 servlet 调用之前/之后运行。
    【解决方案2】:

    我添加的是一个运行状况检查探针,它将使用curl 检查服务器是否仍在运行,我认为可以对其进行修改以检查是否也存在“标志”文件。我只是发送一个catalina.sh stop 命令。

    如果这是一个 Docker 容器,您可以使用 healthcheck 探针让它自己关闭。

    理想情况下,如果您可以迁移到运行 tomcat 但如果 Spring 上下文未正确加载则终止它的 Spring Boot 之类的东西。

    【讨论】:

      猜你喜欢
      • 2014-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-27
      • 1970-01-01
      • 2017-02-01
      • 2016-08-28
      • 1970-01-01
      相关资源
      最近更新 更多