原文:http://blog.csdn.net/u014137486/article/details/54381249
Linux下使用shutdown.sh脚本关闭tomcat无法使得JVM关闭
近日在Linux中部署项目时发现服务无法启动,上一次出现这种问题是kill掉了相关进程,但是并未分析原因,这次又出现了这个问题,于是便分析了一下,分析的基本原因如下:
通过shutdown.sh脚本关闭tomcat时无法关闭JVM进程,导致JVM进程越来越多,占据了大量的内存空间,使得新程序在启动JVM时由于内存不够用而无法启动。
以前的做法是使用命令kill掉占据的无用进程,我在改写了一下tomcat关闭脚本,每次在通过shutdown.sh脚本关闭tomcat时都会强制kill掉所有相关进程,如下:
说明:笔者改写了tomcat bin目录下的catalina.sh文件中的stop部分,因为在关闭tomcat时,会匹配stop if语句,因此笔者便在该模块最后添加了kill进程的语句,
elif [ "$1" = "stop" ] ; then
shift
SLEEP=5 if [ ! -z "$1" ]; then echo $1 | grep "[^0-9]" >/dev/null 2>&1 if [ $? -gt 0 ]; then SLEEP=$1 shift fi fi
FORCE=0 if [ "$1" = "-force" ]; then shift FORCE=1 fi
if [ ! -z "$CATALINA_PID" ]; then if [ -f "$CATALINA_PID" ]; then if [ -s "$CATALINA_PID" ]; then kill -0 `cat "$CATALINA_PID"` >/dev/null 2>&1 if [ $? -gt 0 ]; then echo "PID file found but no matching process was found. Stop aborted." exit 1 fi else echo "PID file is empty and has been ignored." fi else echo "\$CATALINA_PID was set but the specified file does not exist. Is Tomcat running? Stop aborted." exit 1 fi fi
eval "\"$_RUNJAVA\"" $LOGGING_MANAGER $JAVA_OPTS \ -Djava.endorsed.dirs="\"$JAVA_ENDORSED_DIRS\"" -classpath "\"$CLASSPATH\"" \ -Dcatalina.base="\"$CATALINA_BASE\"" \ -Dcatalina.home="\"$CATALINA_HOME\"" \ -Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \ org.apache.catalina.startup.Bootstrap "$@" stop
# stop failed. Shutdown port disabled? Try a normal kill. if [ $? != 0 ]; then if [ ! -z "$CATALINA_PID" ]; then echo "The stop command failed. Attempting to signal the process to stop through OS signal." kill -15 `cat "$CATALINA_PID"` >/dev/null 2>&1 fi fi
if [ ! -z "$CATALINA_PID" ]; then if [ -f "$CATALINA_PID" ]; then while [ $SLEEP -ge 0 ]; do kill -0 `cat "$CATALINA_PID"` >/dev/null 2>&1 if [ $? -gt 0 ]; then rm -f "$CATALINA_PID" >/dev/null 2>&1 if [ $? != 0 ]; then if [ -w "$CATALINA_PID" ]; then cat /dev/null > "$CATALINA_PID" # If Tomcat has stopped don't try and force a stop with an empty PID file FORCE=0 else echo "The PID file could not be removed or cleared." fi fi echo "Tomcat stopped." break fi if [ $SLEEP -gt 0 ]; then sleep 1 fi if [ $SLEEP -eq 0 ]; then echo "Tomcat did not stop in time." if [ $FORCE -eq 0 ]; then echo "PID file was not removed." fi echo "To aid diagnostics a thread dump has been written to standard out." kill -3 `cat "$CATALINA_PID"` fi SLEEP=`expr $SLEEP - 1 ` done fi fi
KILL_SLEEP_INTERVAL=5 if [ $FORCE -eq 1 ]; then if [ -z "$CATALINA_PID" ]; then echo "Kill failed: \$CATALINA_PID not set" else if [ -f "$CATALINA_PID" ]; then PID=`cat "$CATALINA_PID"` echo "Killing Tomcat with the PID: $PID" kill -9 $PID while [ $KILL_SLEEP_INTERVAL -ge 0 ]; do kill -0 `cat "$CATALINA_PID"` >/dev/null 2>&1 if [ $? -gt 0 ]; then rm -f "$CATALINA_PID" >/dev/null 2>&1 if [ $? != 0 ]; then if [ -w "$CATALINA_PID" ]; then cat /dev/null > "$CATALINA_PID" else echo "The PID file could not be removed." fi fi echo "The Tomcat process has been killed." break fi if [ $KILL_SLEEP_INTERVAL -gt 0 ]; then sleep 1 fi KILL_SLEEP_INTERVAL=`expr $KILL_SLEEP_INTERVAL - 1 ` done if [ $KILL_SLEEP_INTERVAL -lt 0 ]; then echo "Tomcat has not been killed completely yet. The process might be waiting on some system call or might be UNINTERRUPTIBLE." fi fi fi fi # Add by afei on 2016-12-09 start # find pid of /home/test/tomcat ,then kill force PIDS echo "Force kill PIDS begin:" ps -ef | grep /home/test/tomcat | grep -v grep | grep -v catalina.sh | awk '{print $2}' | xargs echo ps -ef | grep /home/test/tomcat | grep -v grep | grep -v catalina.sh | awk '{print $2}' | xargs kill -9 echo "Force kill PIDS end!" # Add by afei on 2016-12-09 end
elif [ "$1" = "configtest" ] ; then |
主要是语句“ps -ef | grep /home/test/tomcat | grep -v grep | grep -v catalina.sh |awk '{print $2}' | xargs kill -9”,意思是先根据关键字“/home/test/tomcat”找出匹配的tomcat开启的JVM进程,然后再过滤掉grep进程(执行该条命令的进程)和catalina.sh进程(执行catalina.sh脚本的进程),接着使用awk命令输出“ps -ef”的第二个输出参数信息(即PID),最后使用kill -9强制kill掉相应进程。
附录
参考资料:
[1]. http://blog.csdn.net/u012599988/article/details/44458083
[2]. http://blog.csdn.net/caicongyang/article/details/40041901
[3]. http://blog.csdn.net/yohoph/article/details/41947623
[4]. http://vekergu.blog.51cto.com/9966832/1623700
[5]. http://han.guokai.blog.163.com/blog/static/1367182712010731149286/