玩转Linux Shell编程(八)、Tomcat启动脚本分析

119 阅读1分钟
  1. Linux Shell和基本指令
  2. Bash shell语法
  3. 正则表达式
  4. 文本处理之grep
  5. 文本处理之sed
  6. 文本处理之awk
  7. Text GUI编程
  8. Tomcat启动脚本分析
  9. gradlew脚本分析

前言

不仅要知道如何启动、关闭tomcat,还要知道tomcat的启动脚本都做了些什么事情。

这篇只针对linux下,window下的逻辑也大同小异,只是语法上的差别。

在此之前,我们需要知道如何根据指定的Main Class启动一个jar,通常Main Class都是在jar中的的清单文件中配置,然后通过java -jar xx.jar启动,但有时候也可以通过java -classpath ./xx.jar com.xx.Main在后面指定一个Main Class,而tomcat就是这种方式做的。

tomcat中的Main Class在bin/bootstrap.jarorg.apache.catalina.startup.Bootstrap下,启动过程则是收集一些必要参数,然后传递给Main函数和JVM。

启动过程

startup.sh

这个脚本并不是启动过程的关键,在这个脚本中,做的事情不多,主要是获取到catalina.sh脚本的相对路径并调用,比如startup.sh在bin目录下,你在终端中进入这个bin,然后执行./startup.sh,那么其中有个参数PRGDIR则是./,如果你在上一层执行,如./bin/startup.sh,那么PRGDI将会是./bin,然后PRGDI会拼接上catalina.sh,然后调用,如下。

exec "$PRGDIR"/"$EXECUTABLE" start "$@"

start$@是参数,$@表示传入脚本的所有参数。

catalina.sh

shutdown.sh和startup.sh都会调用 catalina.sh处理,只是参数不同,startup.sh的话第一个参数为start

系统检测

下面这段是检测操作系统的,他会根据所在系统,做一些针对特定系统的逻辑,不需要关心。

cygwin=false
darwin=false
os400=false
hpux=false
case "`uname`" in
CYGWIN*) cygwin=true;;
Darwin*) darwin=true;;
OS400*) os400=true;;
HP-UX*) hpux=true;;
esac

设置CATALINA_HOME、CATALINA_BASE

设置CATALINA_HOME和CATALINA_BASE变量值

[ -z "$CATALINA_HOME" ] && CATALINA_HOME=`cd "$PRGDIR/.." >/dev/null; pwd`

[ -z "$CATALINA_BASE" ] && CATALINA_BASE="$CATALINA_HOME"

调用setenv设置变量

调用setenv.sh设置变量,这个文件是留给我们自定义环境变量的,比如设置JAVA_HOME,他默认不存在,需要我们手动创建。

if [ -r "$CATALINA_BASE/bin/setenv.sh" ]; then
  . "$CATALINA_BASE/bin/setenv.sh"
elif [ -r "$CATALINA_HOME/bin/setenv.sh" ]; then
  . "$CATALINA_HOME/bin/setenv.sh"
fi

可以在其中设置JAVA_HOME,可以供我们设置的变量名在catalina.sh的开头已经全部列举出来了,这里就不说了。

export JAVA_HOME=/usr/lib/jvm/java-11

获取java路径

还有一个脚本setclasspath.sh用来设置_RUNJAVA变量,他存储着java的执行路径。

if [ -r "$CATALINA_HOME"/bin/setclasspath.sh ]; then
    . "$CATALINA_HOME"/bin/setclasspath.sh

获取到bootstrap路径

CLASSPATH="$CLASSPATH""$CATALINA_HOME"/bin/bootstrap.jar

run启动

一般都是通过./startup.sh启动,但是关闭时候需要通过shutdown.sh关闭,如果我们想在终端运行后通过Ctrl+C这种方式随时关闭,可以执行./catalina.sh run,而他最终会执行下面这条命令。

   eval exec "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER "$JAVA_OPTS" "$CATALINA_OPTS" \
      -D$ENDORSED_PROP="\"$JAVA_ENDORSED_DIRS\"" \
      -classpath "\"$CLASSPATH\"" \
      -Dcatalina.base="\"$CATALINA_BASE\"" \
      -Dcatalina.home="\"$CATALINA_HOME\"" \
      -Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
      org.apache.catalina.startup.Bootstrap "$@" start

_RUNJAVA变量是Java的路径,而后面一些是参数,如日志配置,类路径,最后一个 org.apache.catalina.startup.Bootstrap表示运行的主函数所在类,以及传递给主函数的参数。

start启动

如果参数是start,那么表示后台运行,那么需要在命令前面加nohup,以及在命令后面加&,这种方式在linux中表示让程序在后台运行。

eval $_NOHUP "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER "$JAVA_OPTS" "$CATALINA_OPTS" \
      -D$ENDORSED_PROP="\"$JAVA_ENDORSED_DIRS\"" \
      -classpath "\"$CLASSPATH\"" \
      -Dcatalina.base="\"$CATALINA_BASE\"" \
      -Dcatalina.home="\"$CATALINA_HOME\"" \
      -Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
      org.apache.catalina.startup.Bootstrap "$@" start \
      >> "$CATALINA_OUT" 2>&1 "&"

stop终止

tomcat终止的办法是通过一个Socket监听,如果接收到SHUTDOWN字符的话,那么则退出,还有是在start启动后,如果配置了pid文件,则向这个pid文件写入tomcat的进程id,在执行stop命令时,会通过kill -0先检测进程是否正常。

eval "\"$_RUNJAVA\"" $LOGGING_MANAGER "$JAVA_OPTS" \
    -D$ENDORSED_PROP="\"$JAVA_ENDORSED_DIRS\"" \
    -classpath "\"$CLASSPATH\"" \
    -Dcatalina.base="\"$CATALINA_BASE\"" \
    -Dcatalina.home="\"$CATALINA_HOME\"" \
    -Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
    org.apache.catalina.startup.Bootstrap "$@" stop