红联Linux门户
Linux帮助

Linux下使用shutdown.sh脚本关闭tomcat无法使得JVM关闭

发布时间:2017-01-15 10:26:52来源:linux网站作者:去过桃花岛吗
近日在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掉相应进程。
 
本文永久更新地址:http://www.linuxdiyf.com/linux/27827.html