【问题标题】:Tomcat shutting down by itselfTomcat自行关闭
【发布时间】:2014-06-23 05:39:54
【问题描述】:

我在 CentOS 6.5 64 位和 OpenJDK 1.7 64 上运行 Tomcat 7.0.53。

我有几台服务器,偶尔——比如每周随机一次——Tomcat 会优雅地自行关闭。我已经看了几个月了,找不到原因。唯一的模式似乎是在很长一段时间内什么都没有发生,然后关闭。

  • 我已升级到最新版本的底层工具(Tomcat、Java 等)
  • 我正在使用默认内存设置运行
  • 我在 server.xml 中禁用了 SHUTDOWN
  • 我已将 MySQL 移至另一个盒子,以确保 Tomcat 是唯一的实质性应用程序(服务器也运行 nginx)
  • 我已验证我的任何代码中都没有 System.exit()。我没有扫描库,因为我不知道该怎么做。而且我也不指望我会在那里找到任何东西。为什么图书馆会退出?
  • 我已启用垃圾收集的日志记录。但它们看起来非常快 - 就像 0.15 秒内的完整 GC 一样

这是其中一台服务器的内存使用情况。大量可用内存。

                 total       used       free     shared    buffers     cached
    Mem:          2006        771       1234          0        176        281
    -/+ buffers/cache:        313       1692
    Swap:         2047          0       2047

以下是 Catalina.out 中的事件之一。你可以看到它开始了,然后几个小时没有任何令人兴奋的事情。然后像被告知那样优雅地关闭自己。

我已经对此进行了彻底的研究,但一直无法解决这个问题。

有人可以为我提出一个行动计划吗?

谢谢

来自 Server.xml:

    <Server port="-1" shutdown="__SHUTDOWN__">

来自 Catalina.out:

Apr 28, 2014 5:34:50 PM org.apache.tomcat.util.digester.SetPropertiesRule begin
WARNING: [SetPropertiesRule]{Server/Service/Engine/Host/Valve} Setting property 'remoteIpProxiesHeader' to 'x-forwarded-by' did not find a matching property.
Apr 28, 2014 5:34:50 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-apr-8080"]
Apr 28, 2014 5:34:50 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["ajp-apr-8009"]
Apr 28, 2014 5:34:50 PM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 3247 ms
Apr 28, 2014 5:34:50 PM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Catalina
Apr 28, 2014 5:34:50 PM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/7.0.53
Apr 28, 2014 5:34:59 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-apr-8080"]
Apr 28, 2014 5:34:59 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-apr-8009"]
Apr 28, 2014 5:34:59 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 8278 ms
Apr 28, 2014 5:41:53 PM org.apache.jasper.compiler.TldLocationsCache tldScanJar
INFO: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
Apr 28, 2014 10:32:32 PM org.apache.coyote.AbstractProtocol pause
INFO: Pausing ProtocolHandler ["http-apr-8080"]
Apr 28, 2014 10:32:32 PM org.apache.coyote.AbstractProtocol pause
INFO: Pausing ProtocolHandler ["ajp-apr-8009"]
Apr 28, 2014 10:32:32 PM org.apache.catalina.core.StandardService stopInternal
INFO: Stopping service Catalina
Apr 28, 2014 10:32:32 PM org.apache.coyote.AbstractProtocol stop
INFO: Stopping ProtocolHandler ["http-apr-8080"]
Apr 28, 2014 10:32:32 PM org.apache.coyote.AbstractProtocol stop
INFO: Stopping ProtocolHandler ["ajp-apr-8009"]
Apr 28, 2014 10:32:32 PM org.apache.coyote.AbstractProtocol destroy
INFO: Destroying ProtocolHandler ["http-apr-8080"]
Apr 28, 2014 10:32:32 PM org.apache.coyote.AbstractProtocol destroy
INFO: Destroying ProtocolHandler ["ajp-apr-8009"]
May 05, 2014 8:10:32 PM org.apache.catalina.core.AprLifecycleListener init
INFO: Loaded APR based Apache Tomcat Native library 1.1.29 using APR version 1.3.9.
May 05, 2014 8:10:32 PM org.apache.catalina.core.AprLifecycleListener init
INFO: APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true].
May 05, 2014 8:10:32 PM org.apache.tomcat.util.digester.SetPropertiesRule begin

【问题讨论】:

  • 使用分析器实时评估应用程序。您还应该分析堆转储和线程转储,以便更好地了解应用程序中的问题。
  • 很难说,但是tomcat关机一般是因为一两件事。 1)它正在泄漏 ThreadLocals,检查您的 JDBC 驱动程序,这是最常见的来源。 2) 服务器或其应用程序之一已不可恢复地崩溃(例如在本机代码中)。编辑:还明确调用关闭挂钩。 :)
  • 我最初的直觉是,这不是从服务器内部发生的,而是操作系统中的某些东西导致关机。但我一点也不知道这可能是什么神奇的过程。
  • 在 server.xml 中更改您的 tomcat 端口(特别是您的关闭端口)并更新您的 tomcat 脚本,该脚本在调用时关闭/开始记录并拍摄正在运行的快照。另外,您是否有多个版本的 tomcat 正在运行或其他可能会影响您的关闭侦听器端口的东西?
  • 检查您的应用程序没有内存泄漏查看这里的第二个答案stackoverflow.com/questions/6470651/…

标签: java linux tomcat


【解决方案1】:

有东西告诉 Tomcat 关闭。

Tomcat 在“遇到问题”(内存不足或其他任何问题)时不会正常关闭。当内存不足时,Linux 不会优雅地关闭进程,它会使用 kill -9 硬停止它们,这在 Tomcat 日志中不会留下任何痕迹。

  • kill -15 将通过关闭挂钩优雅地关闭 tomcat。 (前面的答案在这里说kill -3,简直就是造成线程转储。)

  • 内部 exit() 也会优雅地关闭它,再次通过关闭挂钩。

  • 可以通过 JMX 关闭,当然也可以通过 Catalina 的关闭命令。

所以,某个地方的某个人告诉 Tomcat 这样做。这不是一些未知的内部“问题”。那种东西直接杀死tomcat,他们不礼貌地问。

您可能会尝试的一件事是启用 DEBUG 以进行日志记录,以查看您收到的内容。如果你得到太多,你可以尝试专门查看org.apache.catalina.core.StandardContext。这可能不会为您提供比已记录更多的信息,但它可能会告诉您一些事情。

之后,如果有这样的动机,并且继续下去,我建议自己构建 Tomcat,并插入一些堆栈跟踪转储。

例如在org.apache.coyote.AbstractProtcol中,可以添加:

Exception e = new Exception("Shut down trace");
getLog().info("Shutting down protocol", e);

stop() 方法。

这将为您提供可靠的堆栈跟踪,以了解其来源。 Tomcat 并不是一个令人讨厌的事件风暴,只是随机消息四处飘荡。关闭是相当同步的。因此,该堆栈跟踪将为您提供有关谁开始聚会的可靠线索。然后你可以从那里看看是怎么发生的。

Tomcat 中有一堆接口和抽象,但实际上只有几个实现,所以它不是不可理解的。并且有一个吸烟堆栈跟踪将极大地帮助确定它。

【讨论】:

  • 关于在stop() 方法中注入我们自己的日志的要点
  • 上面的小错字:kill -3 (SIGQUIT) 不会杀死 JVM,但会产生线程转储(您的意思是 kill -15 (SIGTERM) 确实优雅地关闭了 JVM 并激活了各种关闭钩子) .
【解决方案2】:

您的 Tomcat 是如何启动的?如果有父进程,则发送给父进程的信号可能会导致彻底关闭。

【讨论】:

    【解决方案3】:

    在 v7.0.55 之前的 Tomcat 版本中存在一个已知(且已修复的错误):

    https://bz.apache.org/bugzilla/show_bug.cgi?id=56684

    这个帖子真的很好读,但我可以为你总结一下。当您启动 Tomcat 时,会有一个等待状态,即开始等待关闭命令。这是正常的,但这些版本中的错误是大约 50 天的等待时间的隐式超时。当等待状态超时时,Tomcat 将关闭。

    所以在 Tomcat 中发生了一些奇怪的事情,不,你没有疯。在我发现这个错误并通过升级修复它之前,我维护了一年多的 SOLR 集群发生了这种情况。没有人注意到,因为它花了很长时间才崩溃,而且随着所有事情的发生,很容易忽略找到根本原因。最简单的方法是重新启动 Tomcat,然后忘记它曾经发生过。

    我希望这个答案对你有所帮助。我看到您正在/正在运行带有此错误的版本。

    祝你好运!

    【讨论】:

      【解决方案4】:

      DC/OS 中的一个案例

      最近我们发生了类似的事件。我们的tomcat 作为DC/OS 环境中的服务在docker 中运行。 stderr 只是说 tomcat 被杀掉了,在 tomcat 的任何日志文件中都没有有用的痕迹。

      事实证明,原因很简单,就是我们没有为服务分配足够的内存。更多调试建议是here,但我们使用的关键技术是检查内核日志:

      # journalctl -f _TRANSPORT=kernel
      ...
      Mar 29 15:09:09 host-17 kernel: Memory cgroup out of memory: Kill process 7935 (java) score 1021 or sacrifice child
      Mar 29 15:09:09 host-17 kernel: Killed process 7906 (java) total-vm:11583840kB, anon-rss:1032860kB, file-rss:30924kB, shmem-rss:0kB
      ...
      

      一旦发现,我们在 DC/OS 中增加了对服务的内存分配,问题就解决了。

      【讨论】:

        【解决方案5】:

        您的 Tomcat 是如何启动的?如果有父进程,则发送给父进程的信号可能是干净关闭的原因。我建议在start_script.sh 中添加set -m 选项。

        【讨论】:

          【解决方案6】:

          我在 Jasperserver 和包含的 apache-tomcat 中遇到过这种情况。在setenv.sh 中设置export USE_NOHUP=true 修复了它。

          【讨论】:

            猜你喜欢
            • 2010-11-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-11-17
            • 2016-09-04
            • 2014-05-24
            • 2016-04-02
            相关资源
            最近更新 更多