tomcat进程意外退出的问题分析

1) tomcat不是经过脚本正常关闭(viaport: 即经过8005端口发送shutdown指令)

由于正常关闭(viaport)的话会在 pause 以前有这样的一句warn日志:java

org.apache.catalina.core.StandardServer await
    A valid shutdown command was received via the shutdown port. Stopping the Server instance.
    而后才是 pause -> stop -> destroy
2) tomcat的shutdownhook被触发,执行了销毁逻辑

而这又有两种状况,一是应用代码里有地方用System.exit来退出jvm,二是系统发的信号(kill -9除外,SIGKILL信号JVM不会有机会执行shutdownhook)shell

先经过排查代码,应用方和中间件团队都排查了System.exit在这个应用中使用的可能。那就只剩下Signal的状况了;通过一番排查后,发现每次tomcat意外退出的时间与ssh会话结束的时间正好吻合。apache

有了这个线索以后,银时同窗马上看了一下对方测试环境的脚本,简化后以下:tomcat

$ cat test.sh
#!/bin/bash
cd /data/server/tomcat/bin/
./catalina.sh start
tail -f /data/server/tomcat/logs/catalina.out

tomcat启动为后,当前shell进程并无退出,而是挂住在tail进程,往终端输出日志内容。这种状况下,若是用户直接关闭ssh终端的窗口(用鼠标或快捷键),则java进程也会退出。而若是先ctrl-c终止test.sh进程,而后再关闭ssh终端的话,则java进程不会退出。bash

这是一个有趣的现象,catalina.sh start方式启动的tomcat会把java进程挂到init(进程id为1)的父进程下,已经与当前test.sh进程脱离了父子关系,也与ssh进程没有关系,为何关闭ssh终端窗口会致使java进程退出?ssh

 

若是咱们在test.sh里设置开启做业控制的话,就不会让java进程退出了jvm

#!/bin/bash
set -m  
cd /home/admin/tt/tomcat/bin/
./catalina.sh start
tail -f /home/admin/tt/tomcat/logs/catalina.out

此时java后台进程继承父进程catalina.sh的pgid,而catalina.sh再也不使用test.sh的进程组,而是本身的pid做为pgid,catalina.sh进程在执行完退出后,java进程挂到了init下,java与test.sh进程就彻底脱离关系了,bash也不会再向它发送信号。测试

详情参考:http://hongjiang.info/why-kill-2-cannot-stop-tomcat/,写的很详细。日志

相关文章
相关标签/搜索