抽空仔細讀了一下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/
相關文章
相關標籤/搜索