抽空仔细读了一下tomcat7的相关脚本,获益匪浅,总结一下

我用的是ubunt server,apt-get安装软件源的包,仔细阅读了两个地方的脚本,/etc/init.d/tomcat7/usr/share/tomcat7/bin/catalina.sh两个脚本,感慨颇多,发现之前不少作法都是有问题的,忍不住写博客总结一下。java

/etc/init.d/tomcat7剖析


先说软件源安装的tomcat7,使用service tomcat7 start来 来启动服务,那么脚本的执行入口应该是/etc/init.d/tomcat7,打开这个文件分析一下,几个关键地方标出来,一些不过重要的地方就略过了。 首先让我注意到的是这里:shell

# Make sure tomcat is started with system locale
if [ -r /etc/default/locale ]; then
    . /etc/default/locale
    export LANG
fi

这里有读取系统locale的操做,个人程序中的日志有中文的,结果重启系统以后让tomcat开机自启动,发现日志中的中文全是????,手工重启一下tomcat服务却正常。看到这里了然了,我在配置这个文件时,只写了LC_ALL=zh_CN.UTF-8,而tomcat的service脚本是直接source这个文件的,读取的是LANG这个变量。 因此当时百思不得其解,明明locale命令输出当前环境是zh_CN.UTF-8,为什么系统重启后开机自动启动的tomcat的日志却显示不出中文。果断修改/etc/default/locale,加上一行LANG=zh_CN.UTF-8bootstrap

# overwrite settings from default file
if [ -f "$DEFAULT" ]; then
    . "$DEFAULT"
fi

这里的解释也很清楚,覆盖service脚本中的默认配置的,开头就有这样的定义DEFAULT=/etc/default/$NAME,也就是说,若是要覆盖service脚本中定义好的变量,不该该去动service脚本,而是直接修改/etc/default/tomcat7这个文件。这个文件在安装好tomcat7以后默认是存在的,里面有比较详细的注释,若是要加JVM的内存,应该在这个文件去编辑JAVA_OPTS,而不是直接去改catalina.sh文件,一旦遇到软件包升级,那么配置被覆盖,一切重头再来……ubuntu

catalina.sh剖析


若是是官方tar.gz二进制包解压安装的话,主要的配置是在这里(如centos软件源只有tomcat6,使用tomcat7的话须要用tar.gz解压安装)。centos

catalina.sh自带帮助菜单,咱们先看看这个脚本能实现什么功能吧。tomcat

$ /usr/share/tomcat7/bin/catalina.sh --help
    Using CATALINA_BASE:   /usr/share/tomcat7
    Using CATALINA_HOME:   /usr/share/tomcat7
    Using CATALINA_TMPDIR: /usr/share/tomcat7/temp
    Using JRE_HOME:        /usr/lib/jvm/java-7-openjdk-amd64/
    Using CLASSPATH:       /usr/share/tomcat7/bin/bootstrap.jar:/usr/share/tomcat7/bin/tomcat-juli.jar
    Usage: catalina.sh ( commands ... )
    commands:
      debug             Start Catalina in a debugger
      debug -security   Debug Catalina with a security manager
      jpda start        Start Catalina under JPDA debugger
      run               Start Catalina in the current window
      run -security     Start in the current window with security manager
      start             Start Catalina in a separate window
      start -security   Start in a separate window with security manager
      stop              Stop Catalina, waiting up to 5 seconds for the process to end
      stop n            Stop Catalina, waiting up to n seconds for the process to end
      stop -force       Stop Catalina, wait up to 5 seconds and then use kill -KILL if still running
      stop n -force     Stop Catalina, wait up to n seconds and then use kill -KILL if still running
      configtest        Run a basic syntax check on server.xml - check exit code for result
      version           What version of tomcat are you running?
    Note: Waiting for the process to end and use of the -force option require that $CATALINA_PID is defined

会看到stop-force这个参数,能够在5秒以后若是进程依旧存在就kill掉,适用于没法直接用stop停掉服务的状况。可是注意最后的NOTE,是说-force这个参数必须定义**$CATALINA_PID**这个变量。而这个变量在catalina.sh脚本并未定义,直接没法使用-force参数,接下来咱们一步步读这个脚本,看看如何去定义这个变量。bash

这个脚本仍是很友好的,开始有大量的注释信息,这些注释信息已经告诉了怎么去配置,甚至不用读脚本就已经知道一些东西怎么去配置。好比一开始的注释中就有这样的话:jvm

#   Do not set the variables in this script. Instead put them into a script
#   setenv.sh in CATALINA_BASE/bin to keep your customizations separate.

tomcat已经考虑到了覆盖变量的状况,专门定义了一个setenv.sh脚本用来覆盖内置变量,因此我一开始说直接修改catalina.sh是错误的作法,正确的作法是在$CATALINA_BASH/bin下放一个setenv.sh脚本,这样升级的时候直接覆盖主程序就能够了,不须要由于覆盖掉了catalina.sh而从新配置一遍。而国内的资料几乎千篇一概都是直接编辑catalina.sh,一旦遇到升级的时候可能会由于参数发生变化而挂掉。看到这里的时候我在国外的英文资料上搜索了一下,的确是推荐修改setenv.sh文件,并不是catalina.sh。ui

接下来的注释行是说几个变量的做用是什么,重点关注这几个变量:this

#   CATALINA_HOME   May point at your Catalina "build" directory.
    #
    #   CATALINA_BASE   (Optional) Base directory for resolving dynamic portions
    #                   of a Catalina installation.  If not present, resolves to
    #                   the same directory that CATALINA_HOME points to.
    #   CATALINA_OPTS   (Optional) Java runtime options used when the "start",
    #                   "run" or "debug" command is executed.
    #                   Include here and not in JAVA_OPTS all options, that should
    #                   only be used by Tomcat itself, not by the stop process,
    #                   the version command etc.
    #                   Examples are heap size, GC logging, JMX ports etc.
    #   JAVA_HOME       Must point at your Java Development Kit installation.
    #                   Required to run the with the "debug" argument.
    #
    #   JRE_HOME        Must point at your Java Runtime installation.
    #                   Defaults to JAVA_HOME if empty. If JRE_HOME and JAVA_HOME
    #                   are both set, JRE_HOME is used.
    #   JAVA_OPTS       (Optional) Java runtime options used when any command
    #                   is executed.
    #                   Include here and not in CATALINA_OPTS all options, that
    #                   should be used by Tomcat and also by the stop process,
    #                   the version command etc.
    #                   Most options should go into CATALINA_OPTS.
    #   CATALINA_PID    (Optional) Path of the file which should contains the pid
    #                   of the catalina startup java process, when start (fork) is
    #                   used

CATALINA_HOME:tomcat的build目录所在的路径

CATALINA_BASE:tomcat的主目录,若是没设定,将会指向$CATALINA_HOME

CATALINA_OPTS:当执行start,run,debug时调用的JRE参数,写在这个变量中只有tomcat本身使用,不会被stop进程调用

JAVA_HOME:一目了然,JDK的路径,当系统中有多个JDK版本的时候,这个参数就尤其重要了

JRE_HOME:JRE的路径,若是该变量为空,则指向$JAVA_HOME,若是JRE_HOMEJAVA_HOME都设置了,则JRE_HOME生效

JAVA_OPTS:当任何参数命令执行时都会调用的JRE参数,如version,stop,run等都会调用的JRE参数

CATALINA_PID:遇到直接停不掉的时候,须要stop -force,就必须事先定义这个变量,这个变量存的是一个文件,文件中会写入tomcat启动时的pid,stop -force的时候会打开这个文件,获取pid,若是5秒后进程还在就kill

仅仅看完这个注释以后,咱们就已经知道在tomcat的主目录下创建一个setenv.sh文件,就能够覆盖这些变量了,达到自定义参数的目的。接下来接着往下看。

# resolve links - $0 may be a softlink
    PRG="$0"

    while [ -h "$PRG" ]; do
      ls=`ls -ld "$PRG"`
      link=`expr "$ls" : '.*-> \(.*\)$'`
      if expr "$link" : '/.*' > /dev/null; then
        PRG="$link"
      else
        PRG=`dirname "$PRG"`/"$link"
      fi
    done

发现脚本连软链接的状况都考虑到了,很周全,这一段在说若是脚本是软链接的话,将会转到catalina.sh这个文件真正所在的路径。 好比centos下能够把catalina.sh作一个软链接放到/etc/init.d/tomcat7,经过service tomcat7 start来启动tomcat也是没问题的。

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

能够看到这里在找存在$CATALINA_BASE/bin/setenv.sh$CATALINA_HOME/bin/setenv.sh,就source进来,那么意味着setenv.sh这个文件应该放在tomcat主目录下的bin目录中!这个文件一开始是不存在的,意味着升级的时候直接覆盖bin目录便可。

接下来的脚本是开始作一些处理,当执行脚本参数的时候所执行的操做,好比$CATALINA_PID这个变量存在的时候,会检查这个文件是否可读写,而后把启动进程pid写入这个文件等等。

老版本的catalina.sh在if [ -z "$LOGGING_MANAGER" ]; then这行后面是有一个JAVA_OPTS=的变量设定的(大约240行上下),发现最新的7.0.47版本把很长一段的配置JAVA_OPTS配置给去掉了,对JAVA_OPTS再也不加本身的特殊参数了,看来只能本身写一些JAVA_OPTS参数了。

加JVM的内存的话就修改JAVA_OPTS这个参数好了,网上的资料太多了,就不赘述了。

小结


对于ubuntu的service脚本,能够直接改/etc/default/tomcat7来加内存,若是是centos的service,能够读一下脚本以后,看看是source的哪一个文件,作一样的处理。

对于tar.gz安装的tomcat,新建一个$CATALINA_HOME/bin/setenv.sh文件,增长x权限,参考格式以下:

#!/bin/bash
    CATALINA_PID=$CATALINA_HOME/bin/CATALINA_PID
    JAVA_OPTS="--server -Xmx1280m -XX:+UseConcMarkSweepGC"
    JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64/
相关文章
相关标签/搜索