code up

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

マルチインスタンスのTomcatをサービスで動かす

Linux用のTomcatを複数インスタンスでサービス起動させるためのスクリプトです。 ログのローテーションの設定とちょっとしたApacheの設定まで行います。

Tomcatマルチインスタンス環境の構築

既にTomcatの別インスタンス自体は下記を参考に構築済みです。

startup.shとshutdown.shで起動、停止を行っていたのですが、 jpsで見ても、どれがそのプロセスIDか分からなくなったのでpidを出すようにしたいというのが動機です。

* CATALINA_PIDの環境変数でも出来るようですが、今回の設定が終わってから知りました・・・

jsvcの入手、コンパイル等は下記を参考に。

上記ページのスクリプトでは複数インスタンスに対応してなさそうでしたので下記のスクリプトを作りました。

フォルダがホームディレクトリ以下にあったり、ulimitをわざわざしているのは、 今回の環境では、root権限を持っていないためです。適宜置き換えて下さい。

#!/bin/sh
#
# chkconfig: - 80 15
# description: tomcat-ins2

# Source function library.
. /etc/init.d/functions

# Java
JAVA_HOME=/usr/home/tomcatuser/java
JAVA_OPTS="-Xms128m -Xmx256m -XX:PermSize=128m -XX:MaxPermSize=256m"

# Tomcat
CATALINA_HOME=/usr/home/tomcatuser/tomcat
CATALINA_OPTS=
CLASSPATH=$JAVA_HOME/lib/tools.jar:$CATALINA_HOME/bin/commons-daemon.jar:$CATALINA_HOME/bin/bootstrap.jar

BASEDIR=$CATALINA_HOME
JAVA_ENDORSED_DIRS=$BASEDIR/endorsed

# Multi-instance
TOMCAT_INSTANCE=tomcat-ins2
CATALINA_BASE=/usr/home/tomcatuser/$TOMCAT_INSTANCE
CATALINA_TMPDIR=$CATALINA_BASE/temp
CATALINA_OUT=$CATALINA_BASE/logs/catalina.out

# jsvc
DAEMON=$CATALINA_HOME/bin/jsvc
TOMCAT_USER=tomcatuser
PIDFILE=$CATALINA_BASE/tomcat6.pid
LOCKFILE=$CATALINA_BASE/tomcat6.lock

start(){
    echo -n "Starting jsvc($TOMCAT_INSTANCE): "
    ulimit -n 10240 > /dev/null 2>&1
    $DAEMON \
        -pidfile $PIDFILE \
        -jvm server \
        -user $TOMCAT_USER \
        -home $JAVA_HOME \
        -Dcatalina.base=$CATALINA_BASE \
        -Dcatalina.home=$CATALINA_HOME \
        -Djava.io.tmpdir=$CATALINA_TMPDIR \
        -Djava.endorsed.dirs=$JAVA_ENDORSED_DIRS \
        -Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties \
        -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager \
        -outfile $CATALINA_OUT \
        -errfile '&1' \
        $JAVA_OPTS $CATALINA_OPTS \
        -classpath $CLASSPATH \
        org.apache.catalina.startup.Bootstrap

    RETVAL=$?
    if [ $RETVAL = 0 ]; then
        echo_success
        touch $LOCKFILE
    else
        echo_failure
    fi
    echo
}

stop(){
    echo -n "Shutting down jsvc($TOMCAT_INSTANCE): "
    $DAEMON \
        -stop \
        -pidfile $PIDFILE \
        org.apache.catalina.startup.Bootstrap

    RETVAL=$?
    if [ $RETVAL = 0 ]; then
        echo_success
        rm -f $PIDFILE $LOCKFILE
    else
        echo_failure
    fi
    echo
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        sleep 5
        start
        ;;
    status)
        status $DAEMON
        RETVAL=$?
        ;;
    *)
        echo $"Usage: tomcat-ins2 {start|stop|restart|status}"
        exit 1
        ;;
esac
exit 0

というファイルを$CATALINA_BASEのディレクトリにtomcat-ins2という名前で保存 (/usr/home/tomcatuser/tomcat-ins2/tomcat-ins2)して、後は:

./chmod +x tomcat-ins2 (実行権の付与)

./tomcat-ins2 start で起動
./tomcat-ins2 stop で停止
./tomcat-ins2 restart で再起動
./tomcat-ins2 status で起動しているかの確認

ができるようになりました。

基本的に年1回も再起動しないサーバーなので登録してないですが、 自動起動させたい場合は/etc/rc.d/init.d/などに移動させます。

詳しくは、Tomcatはどこまで“安全”にできるのか?(1)にあります。

ログローテーション

次にログのローテーションです。

Tomcatが出力する*.log, jsvsが出力する*.out, Webアプリケーションが出力する*.txtを例とします。

$CATALINA_BASE/conf/logging.propertiesが標準のままだとファイル名に日付が含まれており ローテートした際、ログの順番が意味分からなくなります。

そこでlogging.propertiesをちょっといじって日付をつけないようにしておきます。

* 余分なコメントやmanager等は使ってないものは削除してあります。
参考にしたURL:
Logging in Tomcat
How to configure log rotation in Apache Tomcat 5.5 and 6.0 using the Juli logging package
Java6 SDK
handlers = \
	1catalina.java.util.logging.FileHandler, \
	2localhost.java.util.logging.FileHandler, \
	java.util.logging.ConsoleHandler

.handlers = 1catalina.java.util.logging.FileHandler, \
	java.util.logging.ConsoleHandler

############################################################
# Handler specific properties.
# Describes specific configuration info for Handlers.
############################################################

1catalina.java.util.logging.FileHandler.level = FINE 
1catalina.java.util.logging.FileHandler.pattern = ${catalina.base}/logs/catalina.log

2localhost.java.util.logging.FileHandler.level = FINE
2localhost.java.util.logging.FileHandler.pattern = ${catalina.base}/logs/localhost.log

java.util.logging.ConsoleHandler.level = FINE
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

############################################################
# Facility specific properties.
# Provides extra control for each logger.
############################################################

org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.java.util.logging.FileHandler

Tomcatはどこまで“安全”にできるのか?(2)を参考に、/etc/logrotate.d/にtomcat-ins2という名前のファイルを作成。

上記リンク先の例だとcopytruncateでkill -HUPしてるのですが、copytruncateは(コピー中に出力される)ログを失う可能性があるということなので

Tomcatシャットダウン → ログローテーション → Tomcat起動 としました。

再起動にかかる時間はkill -HUPよりかかりますが、Apacheと連携している場合、kill -HUPでも503エラーになりますのであまり気にしないことにします。

* Tomcatをkill -HUP、Apache2のrestartだと一番ダウンタイムが少ないと思います。今回はそこまでの要求仕様ではないので行いませんでした。

/etc/logrotate.d/tomcat-ins2:

/usr/home/tomcatuser/tomcat-ins2/logs/*.log /usr/home/tomcatuser/tomcat-ins2/logs/*.txt /usr/home/tomcatuser/tomcat-ins2/logs/*.out {
    weekly
    nocreate
    notifempty
    missingok
    sharedscripts
    rotate 4
    compress
    delaycompress
    prerotate
        sudo -u tomcatuser /usr/home/tomcatuser/tomcat-ins2/tomcat-ins2 stop 2> /dev/null || true
    endscript
    postrotate
        sudo -u tomcatuser /usr/home/tomcatuser/tomcat-ins2/tomcat-ins2 start 2> /dev/null || true
    endscript
}

試す(手動でログのローテーションを実行する)には

logrotate -f /etc/logrotate.d/tomcat-ins2

です。

実行時間は、/etc/crontab内のcron.dailyの部分で定義されています。

02 4 * * * root run-parts /etc/cron.daily

だいたいのディストリビューションで、4:02のようです。

そして、毎日4:02になると/etc/cron.dailyにあるスクリプトが実行されて、この中のlogrotateというスクリプトが/etc/logrotate.dの中にある設定ファイルを読み込んで実行します。

* 今回の場合はtomcat-ins2

weeklyとしてあれば、毎日読み込まれますが、実際に実行されるのは週1回となります。

実行結果は、/var/lib/logrotate.statusに記録されています。

Apacheの設定ファイルを少し変更

Apacheとmod_proxyで連携してたりするとローテーションした直後503エラーが出るようになってしまいます。 mod_proxyだとデフォルトでは60秒間くらい復帰しないので、もう少し早く復帰するようにします。

Apacheのmod_proxyの部分で以下のように設定します。

ProxyPass ajp://localhost:8009/myapp/ retry=3 nocanon

retry=0でもいけるっぽいですが、 アプリケーションサーバーのメンテナンスを実施した際に全ての接続を常に後ろに確認しにいくことになりますので、 1以上を指定してほどよく確認というのが良さそうです。

海外のメーリングリストでは0にするとconfigtestでSyntax Errorになるという報告があります(2.2.10)。 → [users@httpd] Re: httpd/2.2 Mod_proxy ProxyPass retry

いきなり再起動するのではなく、apachectl configtestで確認をしてから再起動しましょう!

環境
Red Hat Enterprise Linux AS release 4 (Nahant Update 4)
Apache 2.2
Tomcat 6.0
関連記事
タグ:Linux Tomcat
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。