30 May 2018
因为安全问题,在线上运行tomcat一般不用root权限来运行,而是采用非root用户来运行。
tomcat7 官方daemon运行文档
# step 0. 准备java环境 及 编译环境 # 提前下载jdk(本例中将jdk放置在/usr/local/java目录中) yum install gcc gcc-c++ make autoconf -y # step 1. 安装tomcat wget http://mirror.rise.ph/apache/tomcat/tomcat-7/v7.0.88/bin/apache-tomcat-7.0.88.tar.gz tar zxvf apache-tomcat-7.0.88.tar.gz mv apache-tomcat-7.0.88 /usr/local/tomcat # step 2. 编译jsvc cd /usr/local/tomcat/bin tar zxvf commons-daemon-native.tar.gz cd commons-daemon-1.1.0-native-src/unix/ ./configure --with-java=/usr/local/java make # --with-java参数可手动指定JAVA_HOME路径,若不指定,则默认寻找系统环境中的JAVA_HOME变量 # step 3. 拷贝jsvc到tomcat的bin目录 cp jsvc ../.. cd ../..
此时我们的软件环境已经准备完毕,能够用采用unix daemon模式启动tomcat,核心在于jsvc命令。例如我们可以使用以下命令来启动tomcat
CATALINA_BASE=$CATALINA_HOME cd $CATALINA_HOME ./bin/jsvc \ -classpath $CATALINA_HOME/bin/bootstrap.jar:$CATALINA_HOME/bin/tomcat-juli.jar \ -outfile $CATALINA_BASE/logs/catalina.out \ -errfile $CATALINA_BASE/logs/catalina.err \ -Dcatalina.home=$CATALINA_HOME \ -Dcatalina.base=$CATALINA_BASE \ -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager \ -Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties \ org.apache.catalina.startup.Bootstrap
可以使用jsvc --help查看更多选项,其中一个比较重要的选项就是-user,使用这个参数可以指定另外一个用户来启动tomcat daemon。
jsvc提供了$CATALINA_HOME/bin/daemon.sh文件来替代上面的命令行模式来启动tomcat.
我们有两种定义它的方式,
daemon.sh其他重要参数:
CATALINA_OUT, catalina.out的位置JAVA_OPTS, jvm options
个人推荐第二种,下面是可使用的自定义参数
--java-home,会传给jsvc的-java-home,默认使用系统环境java命令来判断JAVA_HOME--catalina-home,会传给jsvc的-Dcatalina.home,默认使用当前daemon.sh脚本所在目录的上级目录作为catalina.home--catalina-base,会传给jsvc的-Dcatalina.base,默认和–catalina-home值相同--tomcat-user,回传给jsvc的-user,默认竟然是tomcat用户自定义部分
# 自定义catalina.out日志位置 # 注释下一行内容 # test ".$CATALINA_OUT" = . && CATALINA_OUT="$CATALINA_BASE/logs/catalina-daemon.out" # 自定义为其他位置 CATALINA_OUT="$CATALINA_BASE/logs/catalina-daemon.out"
# 增加tomcat用户 groupadd tomcat useradd -s /sbin/nologin -g tomcat tomcat # 将tomcat目录属主和属组修改为刚创建的tomcat用户 chown -R tomcat.tomcat /usr/local/tomcat
可以通过以下脚本放在/etc/init.d/中来充当tomcat的启动脚本
#!/bin/bash # chkconfig: 2345 20 80 # description: script for tomcat start CATALINA_HOME=/usr/local/tomcat CATALINA_BASE=$CATALINA_HOME TOMCAT_USER=tomcat JAVA_HOME=/usr/local/java function jsvc_exec() { ${CATALINA_HOME}/bin/daemon.sh \ --java-home $JAVA_HOME \ --catalina-home $CATALINA_HOME \ --catalina-base $CATALINA_BASE \ --tomcat-user $TOMCAT_USER \ --service-start-wait-time 50 \ $1 } case "$1" in start ) jsvc_exec start exit $? ;; stop ) jsvc_exec stop exit $? ;; restart ) jsvc_exec stop sleep 2 jsvc_exec start exit $? ;; version ) jsvc_exec version exit $? ;; * ) echo "Unknown command: \`$1'" echo "commands:" echo " restart Retart Tomcat" echo " start Start Tomcat" echo " stop Stop Tomcat" echo " version What version of commons daemon and Tomcat" echo " are you running?" exit 1 ;; esac
脚本启动时会启动一个root进程和一个我们指定的user的解释
另外值得注意的是,root进程负责的是派生我们指定的user来运行的进程,如果杀掉user运行的进程,则root进程会持续派生新的进程出来。
若希望用一个脚本来管理多个同样功能的tomcat,可使用下面的数组脚本
#!/bin/bash # chkconfig: 2345 20 80 # description: script for tomcat start CATALINA_HOMES=(/usr/local/tomcat01 /usr/local/tomcat02) TOMCAT_USER=tomcat JAVA_HOME=/usr/local/java function jsvc_exec() { retval=0 for CATALINA_HOME in ${CATALINA_HOMES[@]} do [ $retval -eq 0 ] || [ $retval -eq 255 ] || break ${CATALINA_HOME}/bin/daemon.sh \ --java-home $JAVA_HOME \ --catalina-home $CATALINA_HOME \ --catalina-base $CATALINA_HOME \ --tomcat-user $TOMCAT_USER \ --service-start-wait-time 50 \ $1 retval=$? done } case "$1" in start ) jsvc_exec start exit $? ;; stop ) jsvc_exec stop exit $? ;; restart ) jsvc_exec stop sleep 2 jsvc_exec start exit $? ;; version ) jsvc_exec version exit $? ;; * ) echo "Unknown command: \`$1'" echo "commands:" echo " restart Retart Tomcat" echo " start Start Tomcat" echo " stop Stop Tomcat" echo " version What version of commons daemon and Tomcat" echo " are you running?" exit 1 ;; esac
--service-start-wait-time 50解决的是tomcat进程启动过慢时,jsvc返回为1的问题。 因为jsvc启动需要等到进程返回”I am ready”时才会返回。 如果这个wait的时间被超过,则返回为1(参考文档)