现象
通过查看tomcat目录下logs/catalina.out 可以看到在异常终止前,有这样的日志:
org.apache.catalina.core.StandardServer await
A valid shutdown command was received via the shutdown port. Stopping the Server instance.
翻译过来的大体意思是:通过关闭端口接收到有效的关闭命令。正在停止服务器实例。
直白点意思就是:有人告诉tomcat叫他别运行了
原因
造成这个现象的原因是我在linux中写了个定时(crontab)重启tomcat的脚本,
tomcat_home="/usr/local/tomcat"
SHUTDOWN=$tomcat_home/bin/shutdown.sh
STARTTOMCAT=$tomcat_home/bin/startup.sh
echo "停tomcat$tomcat_home"
$SHUTDOWN
ps -ef |grep tomcat |grep $tomcat_home |grep -v 'grep'|awk '{print $2}' | xargs kill -9
sleep 20
echo "start $tomcat_home"
$STARTTOMCAT
该脚本通过先调用tomcat的shutdown.sh停止tomcat,然后再检查tomcat是否停止,如果未停止再执行kill杀死tomcat进程,然后再通过startup.sh启动tomcat。光看脚本逻辑,没毛病。
但是当我们通过shutdown.sh终止tomcat时,此时tomcat在linux下是被记录成关闭tomcat服务,此时tomcat的进程记为PID(父进程ID),然后我们再通过startup.sh启动时,此时tomcat的进程ID记为CID(子进程ID)。然后tomcat可能正常运行一段时间,但当linux进行自我优化,即内存回收和垃圾清理时,它扫描的是程序的PID,但此时tomcat的PID已经中止了,所以此时,linux会下令中止tomcat服务,所以tomcat就自刎了!!!
解决办法
修正tomcat重启脚本,不调用shutdown.sh来停止服务,直接kill Tomcat进程
或者直接取消定时任务