tomcat bin目录下已经有了启动、关闭的脚本,写这个脚本主要是为了方便自动化运维,把tomcat和jdk推到服务器上解压后,把这个脚本传到PATH目录下,改个名字,给个执行权限就可以了,可以少设置很多东西,同时功能更加丰富。主要有以下几点功能:

  1. 只需配置JDK目录和tomcat目录即可,无需设置全局JDK环境变量和setenv.sh
  2. 可以指定tomcat启动运行的用户
  3. 系统中有多个tomcat时,可以公用一个脚本
  4. 每次启动tomcat都会先检查目录权限和清理临时目录,并调整ulimit,防止应用使用缓存和出现性能问题
  5. 可以查看tomcat运行详细情况,cpu/内存/RSS/VSZ/运行时间等
  6. 可以使用本脚本tail输出 catalina.out
  7. 安全停止tomcat,先正常关闭tomcat,等待一段时间后kill,确保tomcat能够关闭
  8. 可以在tomcat关闭时,清理缓存目录temp/webapp/work
  9. tomcat运行时,可以使用jinfo/jmap/jstack导出jvm信息

都在脚本里,详细的自己看脚本吧。可以实现tomcat start/stop/status/kill/tail/clean/dump等功能。

#!/bin/bash
# Author: Will
# WebSite: https://www.nixops.me
# description: Tomcat multi-function script

 
#tomcat install dir
export CATALINA_HOME=/opt/tomcat-9.0_blog/

#TOMCAT_USER is the default user of tomcat
export TOMCAT_USER=tomcat

#SHUTDOWN_WAIT is wait time in seconds for java proccess to stop
SHUTDOWN_WAIT=5


# add java JDK path
export JAVA_HOME=/opt/jdk1.8
export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin

#####以上是按需修改的地方######

#TOMCAT_USAGE is the message if this script is called without any options
TOMCAT_USAGE="用法: $0 {\e[00;32mstart\e[00m|\e[00;31mstop\e[00m|\e[00;31mkill\e[00m|\e[00;32mstatus\e[00m|\e[00;31mrestart\e[00m|\e[00;32mtail\e[00m|\e[00;32mclean|\e[00;31mdump\e[00m}\n\
参数模式: $0 {\e[00;32m[action] \e[00;31m[tomcat path] \e[00;31m[run user] \e[00m} \n\n


启动参数说明: \n
start: 启动tomcat \n
stop: 正常停止tomcat \n 
kill: 杀掉tomcat进程  \n
status: 查看状态,是否运行/详细的运行状态  \n
restart: 调用stop/start重启tomcat  \n
tail: 使用tail命令查看catalina.out日志 \n  
clean: tomcat关闭时,清理缓存目录temp/webapp/work \n
dump: 使用jinfo/jmap/jstack导出jvm信息 \n\n

参数模式主要供脚本调用,或者多个tomcat公用一个init脚本;CATALINA_HOME和TOMCAT_USER通过参数传入,脚本中无需指定,使用方法: \n
$0 启动参数  tomcat路径  运行用户 \n
$0 status /opt/tomcat8/  tomcat \n

"

#Check init script ARGS
if [ "$#" -eq "3" ] ;then
    echo -e "\e[00;32mInit Script Run With Args \e[00m"
    export CATALINA_HOME=$2
    export TOMCAT_USER=$3
  elif [ "$#" -ne "1"  ] ;then
    echo -e $TOMCAT_USAGE
    exit 1
fi

#tomcat work dir
export CATALINA_BASE=$CATALINA_HOME

#Set init Run Env
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:$CATALINA_HOME/bin
export PATH

tomcat_pid() {
  echo `ps -fe | grep $CATALINA_BASE |grep java | grep -v grep | tr -s " "|cut -d" " -f2`

}

tomcat_start_set() {

  if [ `user_exists $TOMCAT_USER` -eq "0" ];
  then
     echo -e "\e[00;31mSystem User:  $TOMCAT_USER not exist \e[00m"
     exit 1 
  elif [ `whoami` !=  "$TOMCAT_USER" ] &&  [ `whoami` != "root" ];
  then
     echo -e "\e[00;31mMust Run as : root or  $TOMCAT_USER \e[00m"
     exit 1 
     
  fi

  chown -R $TOMCAT_USER $CATALINA_HOME $CATALINA_BASE
  echo -e "\e[00;32mSet CATALINA_HOME CATALINA_BASE Permission Done\e[00m"

  if [ ! -z "$CATALINA_BASE" ]; then 
       \rm -rf $CATALINA_BASE/temp/* $CATALINA_BASE/work/* $CATALINA_BASE/webapps/* 
       echo -e "\e[00;32mClean Tomcat work/temp/webapps Done\e[00m"
  fi

  ulimit -n 100000
  umask 007
}
 
start() {
  pid=$(tomcat_pid)
  if [ -n "$pid" ]; then
    echo -e "\e[00;31mTomcat is already running (pid: $pid)\e[00m"
  else
    echo -e "\e[00;32mStarting Tomcat : $CATALINA_HOME\e[00m"

    tomcat_start_set 

    if [ `whoami` = "root" ]
    then
      /bin/su $TOMCAT_USER -c "cd $CATALINA_HOME/bin ; /bin/bash startup.sh"
    else
      cd $CATALINA_HOME/bin ; /bin/bash startup.sh
    fi

    status
  fi
  return 0
}
 
status(){
  pid=$(tomcat_pid)
  if [ -n "$pid" ]; then 
    echo -e "\e[00;32mTomcat is running with pid: \e[00;31m$pid\e[00m"
    ppid=`ps --no-headers  -p $pid -o ppid`
    cpu=`ps --no-headers  -p $pid -o %cpu`
    mem=`ps --no-headers  -p $pid -o %mem`
    user=`ps --no-headers  -p $pid -o user`
    group=`ps --no-headers  -p $pid -o group`
    stime=`ps --no-headers  -p $pid -o stime`
    etime=`ps --no-headers  -p $pid -o etime`
    rss=`ps --no-headers  -p $pid -o rss`
    vsz=`ps --no-headers  -p $pid -o size`
    cmd=`ps --no-headers  -p $pid -o cmd`
    echo -e "\e[00;32mPPID: \e[00;31m$ppid \e[00m"
    echo -e "\e[00;32mRun User: \e[00;31m$user \e[00m"
    echo -e "\e[00;32mRun Group: \e[00;31m$group \e[00m"
    echo -e "\e[00;32mCurrent Tomcat CPU Usage: \e[00;31m$cpu% \e[00m"
    echo -e "\e[00;32mCurrent Tomcat Mem Usage: \e[00;31m$mem% \e[00m"
    echo -e "\e[00;32mRSS Mem: \e[00;31m$rss KB \e[00m"
    echo -e "\e[00;32mVSZ Mem: \e[00;31m$vsz KB \e[00m"
    echo -e "\e[00;32mStart Time: \e[00;31m$stime \e[00m"
    echo -e "\e[00;32mTotal Run Time: \e[00;31m$etime \e[00m"
    echo -e "\e[00;32mStart Cmd: \e[00;31m$cmd \e[00m"

  else 
    echo -e "\e[00;31mTomcat is not running\e[00m"
  fi
}

terminate() {
  pid=$(tomcat_pid)
  if [ -n "$pid" ]; then
     echo -e "\e[00;31mPid: $pid,Terminating Tomcat\e[00m"
     kill -9 $(tomcat_pid)
  else
     echo -e "\e[00;31mTomcat Pid Not Found,Skip Kill !\e[00m"
  fi 
  
}

stop() {
  pid=$(tomcat_pid)
  if [ -n "$pid" ]; then
    echo -e "\e[00;31mStoping Tomcat\e[00m"
    sh $CATALINA_HOME/bin/shutdown.sh
 
    let kwait=$SHUTDOWN_WAIT
    count=0;
    until [ `ps -p $pid | grep -c $pid` = '0' ] || [ $count -gt $kwait ]
    do
      echo -n -e "\n\e[00;31mwaiting for processes to exit\e[00m";
      sleep 1
      let count=$count+1;
    done
 
    if [ $count -gt $kwait ]; then
      echo -n -e "\n\e[00;31mkilling processes didn't stop after $SHUTDOWN_WAIT seconds\e[00m"
      terminate
    fi
  else
    echo -e "\e[00;31mTomcat is not running\e[00m"
  fi
 
  return 0
}
 
user_exists(){
  if id -u $1 >/dev/null 2>&1; then
    echo "1"
  else
    echo "0"
  fi
}
 
tail_log(){
  pid=$(tomcat_pid)
  if [ -n "$pid" ]; then
     echo -e "\e[00;31mPid: $pid,run tail -f $CATALINA_BASE/logs/catalina.out\e[00m"
     tail -n 100 -f $CATALINA_BASE/logs/catalina.out
  else
     echo -e "\e[00;31mTomcat Pid Not Found,Skip Tail Log !\e[00m"
  fi
}

clean(){

  pid=$(tomcat_pid)
  if [ -n "$pid" ]; then
    echo -e "\e[00;31m Tomcat Running With Pid: $pid,Skip Clean\e[00m"
  else
    echo -e "\e[00;32mClean Tomcat logs and work/temp/webapps \e[00m"

    if [ ! -z "$CATALINA_BASE" ]; then
      \rm -rf $CATALINA_BASE/logs/* 
      echo -e "\e[00;32mClean Tomcat logs/* Done\e[00m"
      \rm -rf $CATALINA_BASE/temp/* $CATALINA_BASE/work/* $CATALINA_BASE/webapps/*
      echo -e "\e[00;32mClean Tomcat work/temp/webapps Done\e[00m"
    fi
  fi

}

dump(){
  pid=$(tomcat_pid)
  if [ -n "$pid" ]; then
    echo -e "\e[00;31m Tomcat Running With Pid: $pid,Start  dumping \e[00m"
    JAVA_HOME=`ps --no-headers  -p $pid -o cmd |awk -F bin '{print $1}'`

    if [  -n "$JAVA_HOME" ];then  
        echo -e "\e[00;31m jinfo Dump pid : $pid to /tmp/tomcat_"$pid"_jinfo_`date -I`.log \e[00m"
        $JAVA_HOME/bin/jinfo  $pid > /tmp/tomcat_"$pid"_jinfo_`date -I`.log

        echo -e "\e[00;31m jstack Dump pid : $pid to /tmp/tomcat_"$pid"_jstack_`date -I`.log \e[00m"
        $JAVA_HOME/bin/jstack  -F $pid > /tmp/tomcat_"$pid"_jstack_`date -I`.log

        echo -e "\e[00;31m jmap -heap Dump pid : $pid to /tmp/tomcat_"$pid"_jmap_heap_`date -I`.log \e[00m"
        $JAVA_HOME/bin/jmap  -heap -F $pid > /tmp/tomcat_"$pid"_jmap_heap_`date -I`.log 

        echo -e "\e[00;31m jstat -gcutil Dump pid : $pid to /tmp/tomcat_"$pid"_jstat_gcutil_`date -I`.log \e[00m"
        $JAVA_HOME/bin/jstat -gcutil $pid > /tmp/tomcat_"$pid"_jstat_gcutil_`date -I`.log 

        echo -e "\e[00;31m jmap -histo Dump pid : $pid to /tmp/tomcat_"$pid"_jmap_histo_`date -I`.log ,this action will trigger GC First\e[00m"
        $JAVA_HOME/bin/jmap  -histo -F $pid > /tmp/tomcat_"$pid"_jmap_histo_`date -I`.log 

        echo -e "\e[00;31m jmap -clstats Dump pid : $pid to /tmp/tomcat_"$pid"_jmap_clstats_`date -I`.log , this action will suspend the app \e[00m"
        $JAVA_HOME/bin/jmap  -clstats  -F $pid > /tmp/tomcat_"$pid"_jmap_clstats_`date -I`.log 

        echo -e "\e[00;31m jmap -dump Dump pid : $pid to /tmp/tomcat_"$pid"_jmap_dump_`date -I`.log , this action will suspend the app \e[00m"
        $JAVA_HOME/bin/jmap -dump:live,format=b,file=/tmp/tomcat_"$pid"_jmap_clstats_`date -I`.log  $pid  
          
    else
        echo -e "\e[00;31m Can't found jinfo/jstack/jmap/jstat  under $JAVA_HOME/bin/ , Skip Dump \e[00m"
    fi
    
  else
    echo -e "\e[00;32mTomcat not Running. Skip Dump! \e[00m"
  fi

}

case $1 in
  start)
    start
  ;;
  stop)  
    stop
  ;;
  restart)
    stop
    start
  ;;
  status)
    status
  ;;
  kill)
    terminate
  ;;    
  tail)
    tail_log
  ;;    
  clean)
    clean 
  ;;    
  dump)
    dump
  ;;
  *)
    echo -e $TOMCAT_USAGE
  ;;
esac

exit 0