Java Tomcat自动关机
我在CentOS 6.5 64位和OpenJDK 1.7 64上运行Tomcat 7.0.53 我有几个服务器,偶尔——就像每周随机一次一样——Tomcat会优雅地自行关闭。我已经看了几个月了,找不到原因。唯一的模式似乎是长时间没有任何事情发生,然后关闭Java Tomcat自动关机,java,linux,tomcat,Java,Linux,Tomcat,我在CentOS 6.5 64位和OpenJDK 1.7 64上运行Tomcat 7.0.53 我有几个服务器,偶尔——就像每周随机一次一样——Tomcat会优雅地自行关闭。我已经看了几个月了,找不到原因。唯一的模式似乎是长时间没有任何事情发生,然后关闭 我已经升级到最新版本的底层工具(Tomcat、Java等) 我使用默认内存设置运行 我已在server.xml中禁用关机 我已经将MySQL移到了另一个框中,以确保Tomcat是唯一实质性的应用程序(服务器也运行nginx) 我已经验证了我的
- 我已经升级到最新版本的底层工具(Tomcat、Java等)
- 我使用默认内存设置运行
- 我已在server.xml中禁用关机
- 我已经将MySQL移到了另一个框中,以确保Tomcat是唯一实质性的应用程序(服务器也运行nginx)
- 我已经验证了我的任何代码中都没有System.exit()。我还没有扫描LIB,因为我不知道怎么做。我也不希望在那里找到任何东西。为什么图书馆会退出呢
- 我已启用垃圾收集日志记录。但它们看起来相当快,就像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__">
有东西在告诉Tomcat关机 Tomcat在“遇到麻烦”(内存不足或其他任何情况)时不会优雅地关闭。当内存不足时,Linux不会优雅地关闭进程,它会使用kill-9强制停止进程,这在Tomcat日志中不会留下任何痕迹
将通过关闭钩子优雅地关闭tomcat。(之前的答案是这里的kill-15
,这只是导致线程转储。)kill-3
- 内部出口()也将通过关闭钩子优雅地关闭它
- 它可以通过JMX关闭,当然还有来自Catalina的关闭命令
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中有很多接口和抽象,但实际上只有少数实现,所以它不是不可穿透的。有一个冒烟的堆栈跟踪将非常有助于将其固定下来。您的Tomcat是如何启动的?如果存在父进程,则发送到父进程的信号可能是导致完全关闭的原因。在v7.0.55之前的Tomcat版本中存在一个已知的(已修复的)错误: 这篇文章读起来确实不错,但我可以为你总结一下。启动Tomcat时,会出现一个等待状态,开始等待shutdown命令。这是正常的,但是这些版本中的错误是在大约50天的等待时间内隐式超时。等待状态超时时,Tomcat将关闭 所以在Tomcat中有一些奇怪的事情发生,不,你不是疯子。这发生在我维护了一年多的SOLR集群上,之后我发现了这个bug并通过升级修复了它。没有人注意到,因为崩溃花了太长时间,而且随着时间的推移,找到根本原因变得很容易。最简单的事情就是重新启动Tomcat并忘记它曾经发生过 我希望这个答案对你有帮助。我看到您正在/正在运行带有此错误的版本
祝你好运 DC/OS中的一个案例 最近我们也发生了类似的事件。我们的
tomcat
作为服务在DC/OS
环境中的docker中运行。stderr只是说tomcat被杀了,在tomcat的任何日志文件中都没有有用的痕迹
原来原因很简单,我们没有为服务分配足够的内存。还有更多的调试建议,但我们使用的关键技术是检查内核日志:
# 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中增加了服务的内存分配,问题就解决了。您的Tomcat是如何启动的?如果存在父进程,则发送到父进程的信号可能会导致完全关闭。我建议将
set-m
选项添加到start\u script.sh
中,使用探查器在live中评估应用程序。您还应该分析堆转储和线程转储,以便更好地了解应用程序中的问题。1) 它正在泄漏线程,请检查您的JDBC驱动程序,这是最常见的源代码。2) 服务器或其应用程序之一已无法恢复地崩溃(例如在本机代码中)。编辑:也显式调用关闭挂钩。:)我最初的直觉是,这不是从服务器内部发生的,操作系统中的某些东西正在导致关机。但我一点也不知道什么是魔法
# 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
...