前言
前几天一个同事说我的某个web服务起不来了。这个web服务部署在某个用户目录的一个tomcat A下面,我登上去执行启动脚本的时候,显示启动的是opt目录下的一个tomcat O,但是没有在 tomcat O的日志目录下写日志的权限,所以报错了。
经检查当前tomcat A的配置文件没有修改过,当前用户变量也没有设置相关路径,结果在系统环境变量下面看到设置了export CATALINA_HOME=/opt/…/tomcat。经询问运维同事,最近迁移一些服务到该服务器上,因为共用一个tomcat安装目录,就在系统环境变量中添加了CATALINA_HOME的配置。所以我那个用户下的tomcat再重启就报错了。
一、CATALINA_HOME是什么?
在Tomcat的bin目录下打开catalina.sh可以看到CATALINA_HOME目录指Tomcat的安装目录,是必须的环境变量。与其相近的还有个CATALINA_BASE目录(可选),指Tomcat安装的动态部分的基本目录,如果不设置就指向CATALINA_HOME。
可以看到catalina.sh中显示如果没有指定CATALINA_HOME变量的值,就将当前目录作为CATALINA_HOME的值
# Only set CATALINA_HOME if not already set
[ -z "$CATALINA_HOME" ] && CATALINA_HOME=`cd "$PRGDIR/.." >/dev/null; pwd`
如果没有指定CATALINA_BASE的值,就把CATALINA_HOME的值赋给CATALINA_BASE
# Copy CATALINA_BASE from CATALINA_HOME if not already set
[ -z "$CATALINA_BASE" ] && CATALINA_BASE="$CATALINA_HOME"
所以,启动一个没有设置CATALINA_HOME变量的Tomcat时,默认的home目录就是当前catalina.sh所属的Tomcat目录。
二、多个Tomcat实例共用一个安装目录
1.使用场景
一个服务为了提高并发量,需要在同一台服务器上启动多个实例,或者同一台服务器上多个服务使用的Tomcat版本相同,这时候就可以让多个Tomcat实例共用一个安装目录,这样升级或者维护Tomcat的时候只需要操作一遍即可。
2.如何设置
虽然多个Tomcat实例可以共用一个安装目录,但是每个tomcat监听的端口、输出的日志等是不一样的,这时候可以将CATALINA_HOME指向共用Tomcat目录,而CATALINA_BASE指向每个实例所在的工作目录,工作目录下放置配置文件、日志、进程ID等内容。由于共用Tomcat的CATALINA_HOME路径都是一样的,可以设置在系统环境变量中,这样每个用户下所有的Tomcat 都可以使用。
三、不使用共用Tomcat的安装目录
假设某个服务比较特殊或者是很久以前就部署的,不能使用共用的Tomcat,只想使用自己目录下的Tomcat,如果没有设置系统环境变量CATALINA_HOME的话,直接启动就好了,默认就是启动当前目录下的Tomcat。
假如该服务器已经设置了系统环境变量CATALINA_HOME的话,对于某个用户下只有一个Tomcat的情况,可以在该用户的.bash_profile中设置CATALINA_HOME变量;对于某个用户下有多个Tomcat的情况,只能在特定Tomcat的启动脚本或者catalina.sh中设置。
这里还遇到一个小坑,我为启动报错的Tomcat设置CATALINA_HOME变量时,看到catalina.sh中的注释说不要在catalina.sh脚本中设置变量,而是放到一个setenv.sh脚本中,并把该脚本放到CATALINA_BASE/bin目录下。启动时catalina.sh脚本会自动加载该setenv.sh脚本中的变量。
#
# Environment Variable Prerequisites
#
# 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.
#
# CATALINA_HOME May point at your Catalina "build" directory.
然而并没有起作用,于是看了下catalina.sh脚本的内容,发现加载setenv.sh脚本逻辑如下:
# Ensure that any user defined CLASSPATH variables are not used on startup,
# but allow them to be specified in setenv.sh, in rare case when it is needed.
CLASSPATH=
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_HOME变量的值,而未读取setenv.sh之前CATALINA_HOME指向的是公用Tomcat,脚本执行到此处自然读取公用Tomcat下的setenv.sh。所以我改成在catalina.sh开始的地方设置了一下CATALINA_HOME变量指向当前Tomcat,再启动就没有问题了。