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

来源:互联网 发布:百度竞价排名软件 编辑:程序博客网 时间:2024/05/16 12:39

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/

 

0 0
原创粉丝点击