摘要: 我的环境是ubuntu server,使用apt-get安装软件源自带的tomcat,以前经常遇到需要增加tomcat内存的做法,当时的做法是网上搜索的,几乎千篇一律都是说修改catalina.sh,修改JAVA_OPTS这个部分(国内资料几乎都是),我发现大错特错,我遇到过生产环境这么操作,结果升级tomat之后配置被覆盖,导致JVM内存不够,应用全挂的情况!
我用的是ubunt server,apt-get
安装软件源的包,仔细阅读了两个地方的脚本,/etc/init.d/tomcat7
和/usr/share/tomcat7/bin/catalina.sh
两个脚本,感慨颇多,发现以前很多做法都是有问题的,忍不住写博客总结一下。
先说软件源安装的tomcat7,使用service tomcat7 start来
来启动服务,那么脚本的执行入口应该是/etc/init.d/tomcat7
,打开这个文件分析一下,几个关键地方标出来,一些不太重要的地方就略过了。 首先让我注意到的是这里:
# Make sure tomcat is started with system localeif [ -r /etc/default/locale ]; then . /etc/default/locale export LANGfi
这里有读取系统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-8
。
# overwrite settings from default fileif [ -f "$DEFAULT" ]; then . "$DEFAULT"fi
这里的解释也很清楚,覆盖service脚本中的默认配置的,开头就有这样的定义DEFAULT=/etc/default/$NAME
,也就是说,如果要覆盖service脚本中定义好的变量,不应该去动service脚本,而是直接修改/etc/default/tomcat7
这个文件。这个文件在安装好tomcat7之后默认是存在的,里面有比较详细的注释,如果要加JVM的内存,应该在这个文件去编辑JAVA_OPTS
,而不是直接去改catalina.sh文件,一旦遇到软件包升级,那么配置被覆盖,一切重头再来……
如果是官方tar.gz二进制包解压安装的话,主要的配置是在这里(如centos软件源只有tomcat6,使用tomcat7的话需要用tar.gz解压安装)。
catalina.sh
自带帮助菜单,我们先看看这个脚本能实现什么功能吧。
$ /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参数,接下来我们一步步读这个脚本,看看如何去定义这个变量。
这个脚本还是很友好的,开始有大量的注释信息,这些注释信息已经告诉了怎么去配置,甚至不用读脚本就已经知道一些东西怎么去配置。比如一开始的注释中就有这样的话:
# 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。
接下来的注释行是说几个变量的作用是什么,重点关注这几个变量:
# 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_HOME
和JAVA_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/
转载:https://my.oschina.net/abcfy2/blog/192203